Errors
Errors come back as JSON with a 4xx or 5xx status. The shape follows the endpoint's protocol, so OpenAI and Anthropic SDKs raise their usual exception classes.
Error codes
| Code | Status | When it happens |
|---|---|---|
invalid_api_key | 401 | The API key is missing, malformed, unknown, revoked or expired. An expired key's message names its expiry date. |
account_suspended | 403 | The account is suspended. Every key on it is refused until the suspension ends; contact support. |
account_banned | 403 | The account is banned. Its keys are revoked and the remaining credit is forfeited. |
model_not_found | 404 | The model id isn't an enabled model. List the ids with GET /v1/models. |
unsupported_content | 400 | The request contains an image, video, audio or file part. Only text input is accepted. |
content_policy_violation | 400 | The request was blocked by the automated safety check. |
stateless_only | 400 | A /v1/responses request set previous_response_id. Send the full conversation in input instead. |
invalid_request | 400 | The body failed validation (for example max_tokens missing on /v1/messages, n other than 1, or a tool type other than function (or custom on /v1/responses)), the body is over 16 MiB (status 413), or the model rejected it, for example a prompt longer than the context window. Model rejections keep their own 4xx status and message. |
insufficient_balance | 402 | Your balance can't cover the estimated input plus an output budget of at least 256 tokens. Top up. |
key_spend_cap_reached | 402 | This request's hold, added to the key's settled spend and its other in-flight requests, would pass its daily, monthly or lifetime spend cap. |
rate_limit_exceeded | 429 | Too many requests this minute for the key or for the account, or too many concurrent requests for the account. Per-minute limits send Retry-After. |
capacity_exhausted | 429 | The models stayed saturated through 30 s of retries (trial accounts get no retries), or the gateway is briefly at capacity or restarting (status 503). Wait for Retry-After seconds. Nothing is charged. |
safety_unavailable | 503 | The safety check timed out or failed, so the request was refused rather than sent unchecked. Retry shortly. |
upstream_error | 502 | The model backend failed before producing any output (an unexpected internal fault returns this code with status 500; a brief outage or restart on our side returns it with status 503 and Retry-After). Nothing is charged; retry the request. A non-streaming request whose backend fails mid-response, after producing output, also returns this code (status 502) and is charged for its input and the output generated before the failure. A request cut at the 10-minute time limit, after 2 minutes with no output from the model, or by a restart also returns this code and is charged for its input and the output generated before the cut. |
What content_policy_violation blocks is defined in the acceptable use policy.
OpenAI shape
Used by /v1/chat/completions, /v1/responses, /v1/models and /v1/balance. code is one of the codes above. For example:
{
"error": {
"type": "rate_limit_error",
"code": "capacity_exhausted",
"message": "All capacity for this model is busy. Retry after 5 seconds."
}
}
Anthropic shape
Used by /v1/messages. This shape has no code field, so read the HTTP status and error.type. For example:
{
"type": "error",
"error": {
"type": "invalid_request_error",
"message": "max_tokens is required."
}
}
Error types by status
| Status | OpenAI error.type | Anthropic error.type |
|---|---|---|
| 400 | invalid_request_error | invalid_request_error |
| 401 | authentication_error | authentication_error |
| 402 | insufficient_quota | billing_error |
| 403 | permission_error | permission_error |
| 404 | not_found_error | not_found_error |
| 413 | invalid_request_error | request_too_large |
| 429 | rate_limit_error | rate_limit_error |
| 500, 502, 503 | api_error | api_error |
Headers
x-request-idis on every response, errors included. Quote it when you contact support.Retry-After(in seconds) comes withcapacity_exhausted, with the per-minuterate_limit_exceeded, and with a 503upstream_error(a brief outage or restart on our side).
When to retry
| Error | What to do |
|---|---|
capacity_exhausted | Wait Retry-After seconds, then retry. A 429 means paid requests were already retried for up to 30 seconds; a 503 means the gateway was at capacity or restarting and the request never reached a model. |
rate_limit_exceeded | For the per-minute limit, wait Retry-After seconds. For the concurrency limit, retry when one of your running requests finishes. |
safety_unavailable | Retry after a few seconds. The safety check fails closed: when it can't run, the request is refused rather than forwarded unchecked. |
upstream_error | With status 503, wait Retry-After seconds, then retry. Otherwise retry with exponential backoff. |
insufficient_balance, key_spend_cap_reached | Top up, or raise or wait out the cap. Retrying sooner won't help. |
| Other 4xx | Fix the request. Retrying it unchanged returns the same error. |
Failed requests that produced no output are not charged. See how a request is billed.
Long requests
A non-streaming response is sent in one piece when the model finishes. If that takes longer than about 120 seconds, the network edge in front of the API may close the request and return HTTP 524 (a plain error page, not one of the JSON errors above) before the response arrives. You're still charged for the output generated before the cut. Stream long generations with "stream": true: headers go out as soon as the model accepts the request, and : ping comments keep the connection alive until the first token.