Authentication
How to authenticate a request to the roasOS API and to the MCP server.
Every request needs an API key. Send the key as a bearer token.
One key opens both entry paths. The REST API at https://api.roasos.com and the MCP server at https://mcp.roasos.com/mcp read the same credential. There is no second token to make.
Make a key
Make a key in your workspace settings. You need a Growth plan or a Scale plan. A key has this format:
roasos_sk_0d80bcba7586d8f...Keep your API key secret. The key has full access to your workspace. If a key becomes known to other persons, revoke the key in your settings. Then make a new key.
Use the key
Add the key to the Authorization header of every REST request:
curl https://api.roasos.com/v1/account \
-H "Authorization: Bearer roasos_sk_..."An MCP client sends the same header on the transport. Refer to Connect an AI agent (MCP).
{
"mcpServers": {
"roasos": {
"type": "http",
"url": "https://mcp.roasos.com/mcp",
"headers": { "Authorization": "Bearer roasos_sk_..." }
}
}
}What a bad key answers
| Condition | Response |
|---|---|
No Authorization header | 401 missing_api_key |
A token without the roasos_sk_ prefix | 401 invalid_api_key |
| A revoked key, or an unknown key | 401 invalid_api_key |
Rate limits
Each key carries its own requests-per-minute value. The default is 600 requests each minute. This is a default, not a fixed ceiling: your key row can hold a higher value, up to 1,000.
Two policies run on separate counters. The read limit is the value on your key. The write limit is one fifth of it.
| Policy | Requests | Limit |
|---|---|---|
| Read | Every GET, and every other path | 600 each minute |
| Write | A write to /v1/generations, /v1/avatars, /v1/scenes, /v1/products or /v1/uploads | 120 each minute |
A model endpoint, a workflow and an agent run use the read policy.
Each successful response includes your current limits in these headers:
X-RateLimit-LimitX-RateLimit-RemainingX-RateLimit-Reset
If you go above a limit, roasOS answers 429 rate_limit_exceeded with a Retry-After header. Wait for that time. Then send the request again.
Cost controls
Each key carries its own spend policy. It bounds the price of one call, the daily and monthly budgets, the approval threshold, and the allowed models.
Read the policy of the calling key:
curl https://api.roasos.com/v1/limits \
-H "Authorization: Bearer roasos_sk_..."{
"data": {
"policy": {
"max_credits_per_request": 500,
"approval_threshold_credits": 100,
"allowed_models": null
},
"daily": {
"limit": 2000,
"used": 340,
"remaining": 1660,
"reset_at": "2026-08-23T00:00:00.000Z"
},
"monthly": {
"limit": 40000,
"used": 5120,
"remaining": 34880,
"reset_at": "2026-09-01T00:00:00.000Z"
}
}
}| Field | What it bounds |
|---|---|
policy.max_credits_per_request | The highest price of one paid call |
policy.approval_threshold_credits | The highest price that runs without a human approval |
policy.allowed_models | The models this key may call. null means every model |
daily.limit, monthly.limit | The credits this key may spend in each window |
daily.reset_at, monthly.reset_at | UTC midnight, and the first day of the next month |
The agent pages name the approval threshold auto_approve_up_to_credits. It is the same policy value that GET /v1/limits publishes as policy.approval_threshold_credits.
roasOS refuses a call above one of these bounds before it spends:
| Code | Cause |
|---|---|
403 request_credit_limit_exceeded | The price is above max_credits_per_request |
403 spend_approval_required | The price is above the approval threshold, and no person approved it |
429 daily_credit_budget_exceeded | The key reached its daily credit budget |
429 monthly_credit_budget_exceeded | The key reached its monthly credit budget |
503 limits_unavailable | roasOS cannot read the policy now |
The approval threshold is also the authority that lets an agent run spend without a person. Refer to Ask the agent and to Quotes and credits.