Errors are typed by who can fix them. A 4xx is the request or the policy; a 5xx is the pool or the provider.
Status codes
| Code | Meaning | Retry? |
|---|---|---|
| 400 | A parameter the pinned model cannot honor, named in the message. On /v1/messages, also a malformed request, as Anthropic answers it. On /responses, previous_response_id or a hosted tool type. | No |
| 401 | Missing or invalid API key. | No |
| 402 | Insufficient credit, or the conversation has spent the allowance its routing policy sets in session.max_spend_usd. Top up, or start a new session, or raise the cap. | After fixing |
| 403 | The key is revoked, the account is deactivated or unverified, or the request asked for something the key's routing policy does not allow. The message names what was refused and what is permitted. The policy cases: a tool outside the allow-list; a routing.model_pool or routing.scope wider than the policy's; a routing.optimize or routing.preset the organization has enforced; a model outside the policy's pool on /embeddings, /rerank, /images/generations, /audio/speech, /audio/transcriptions or /videos, or auto on one of those with no model of that type in the pool; a pinned model or pool member that does not meet a rule pool's conditions. | No |
| 404 | Model not found, or a model of the wrong kind for the endpoint. Check GET /models. | No |
| 409 | The conversation was stopped by its owner and cannot continue; start a new session or resume it from Agent runs. Also, a request with this Idempotency-Key is still in progress; retry once it completes, and a video downloaded before it finished, which names the state it is in. | Idempotency only |
| 413 | The body exceeds 1 MiB, base64 images and audio included, or no model in the pool has a large enough context window. | No |
| 422 | Validation failed, an unrecognized field was sent, or an Idempotency-Key was reused with a different body. error.param names the field. | No |
| 429 | Rate limited, or the conversation has used the steps its routing policy allows in session.max_steps. Unlike a rate limit, retrying the same session will not clear the step cap. | Rate limit only |
| 502 | The provider returned an error. The model may be cold. | Yes |
| 503 | No eligible model. With auto this is usually a pool or preset problem rather than an outage: nothing in scope satisfies the request's tools, modality, structured output, or quality floor. A rule pool that admits no model at all is reported first. On /embeddings and /rerank, also a pinned provider that is down with fallback refused. On /images/generations, /audio/speech, /audio/transcriptions and /videos, a model that runs only on an Inferbase route, because those surfaces serve on your own credential alone, or a video job whose credential is no longer connected. | After changing the request or the policy |
| 504 | Every attempt in the fallback chain timed out. | Yes |
Unrecognized parameters are rejected with a 422, not ignored. A parameter that is accepted is either forwarded or refused with a reason, so a 200 always means the request you sent is the request that ran.
The envelope
Error bodies carry both shapes: the OpenAI envelope for OpenAI SDKs, and detail beside it for clients written against the older shape.
{
"error": {
"message": "routing.scope 'all' is wider than the routing policy in force allows ('inferbase'). A request may narrow the policy's scope, never widen it.",
"type": "permission_error",
"param": null,
"code": null,
"request_id": "req-9f2c41d8a6b34e17"
},
"detail": "routing.scope 'all' is wider than the routing policy in force allows ('inferbase'). A request may narrow the policy's scope, never widen it."
}type follows OpenAI's taxonomy by status: invalid_request_error, authentication_error, permission_error, rate_limit_error, insufficient_quota, api_error, so SDK retry logic works unchanged. param names the field when a field is at fault. code carries the routing disposition on a failure after routing began, and is otherwise null. request_id repeats the X-Request-ID header, so a copied error body is enough to raise a support question.
Every exit uses the envelope, including validation failures, rate limits, timeouts, and oversized bodies rejected before routing. A failure after a stream has started arrives as an event shaped {"object": "error", "error": {...}} followed by [DONE], with the routing disposition in code.
On /v1/messages, errors use Anthropic's envelope instead: {"type": "error", "error": {...}, "request_id": "..."}.
Last updated September 10, 2026.