Reference
Errors
The error envelopes, status codes and error codes the API returns, and how to fix each.
Errors from the endpoints that reach a model, and from Key, carry x-request-id. Quote it when you contact support. A request that Deference forwarded to a provider appears in Activity under that id, including one the provider failed. A request that Deference refused before forwarding it, with a 400, 401, 402, 404, 413, 429 or 503 of its own, does not appear there. GET /v1/models/{id} answers an unknown model with a 404 that carries no request id.
OpenAI envelope
Chat completions, Responses, Embeddings, Images, Models and Key return this shape.
{
"error": {
"message": "This account has no credit left. Add credit in the dashboard to continue.",
"type": "insufficient_credit",
"code": "insufficient_credit",
"param": null
}
}Anthropic envelope
Messages returns this shape, which Claude Code parses.
{
"type": "error",
"error": {
"type": "billing_error",
"message": "This account has no credit left. Add credit in the dashboard to continue."
},
"request_id": "req_01K7Z4F2XQ"
}Status and type
| Status | OpenAI type | Anthropic type |
|---|---|---|
| 400 | invalid_request_error | invalid_request_error |
| 401 | authentication_error | authentication_error |
| 402 | insufficient_credit | billing_error |
| 403 | permission_error | permission_error |
| 404 | invalid_request_error | not_found_error |
| 413 | invalid_request_error | request_too_large |
| 429 | rate_limit_error | rate_limit_error |
| 502, 504 | api_error | api_error |
| 503 | api_error | overloaded_error |
Codes
Codes are in error.code in the OpenAI envelope. The Anthropic envelope carries the type only.
| Status | Code | Cause | Fix |
|---|---|---|---|
| 400 | invalid_json | The body is not valid JSON | Send a JSON object |
| 400 | missing_model | The request has no model | Add a model id |
| 400 | invalid_parameter | Images: n is not a whole number from 1 to 10 | Send a valid n |
| 400 | unsupported_parameter | The body sets models, route or provider, a plugins entry that adds a fee, X search or audio input, or sends a file to a model without file input and no free parser | Name one model and drop those fields. For files, add the cloudflare-ai parser or pick a model with file input |
| 400 | unsupported_model | The model bills per search or per song, such as perplexity/sonar-deep-research and the Lyria models | Use another model |
| 401 | missing_api_key | No key was sent | Send Authorization: Bearer sk-df-... or x-api-key |
| 401 | invalid_api_key | The key is not recognized | Copy the key again, or create a new one |
| 401 | api_key_disabled | The key is disabled | Enable it in API keys, or use another key |
| 401 | api_key_expired | The key passed its expiry | Create a new key |
| 402 | insufficient_credit | The account has no available credit, or less than the request's hold. A file, image or video given as a URL is held at the model's whole context window | Add credit, lower max_tokens, or send fewer URL inputs |
| 402 | key_limit_reached | The key hit its credit limit, or has less left than the request's hold | Raise the limit, lower max_tokens or use another key |
| 402 | free_credit_not_eligible | The account has only free credit, and this model or request does not qualify | Use an open-weight text model, set a lower max_tokens, or add credit |
| 404 | model_not_found | The model id is not in the catalog | List models and pick a current id |
| 413 | request_too_large | The body is over 32 MB, or 64 MB on Images | Send a smaller body |
| 429 | rate_limited | Too many requests in a minute | Wait for retry-after seconds |
| 429 | too_many_concurrent_requests | 8 requests are already running on the key | Retry when one finishes |
| 502 | upstream_error | The model provider returned an error | Retry the request |
| 503 | service_unavailable | Inference is temporarily unavailable | Retry shortly |
| 504 | upstream_timeout | The provider did not answer in time: 15 minutes for a call that is not streamed, 120 seconds for Images. The call may still have run, so the credit held for it is charged | Retry, or stream the request |
free_credit_not_eligible explains itself: its message lists what free credit pays for and suggests max_tokens. See Free credit.
Provider errors
Errors that describe your request pass through from the provider: 400, 403, 404, 408, 413, 422 and 429. Anthropic-format bodies are returned unchanged. A provider 401 or 402, which concerns Deference's own upstream account, returns 503. Any other provider failure returns 502. Both carry your request id and never reveal the upstream account.
Failures after a stream starts
A stream that fails midway still returns HTTP 200, and the error arrives as an event in the stream. Activity marks that request failed. A failed request is charged only for what the provider reports. See Streaming events.
Retry
Retry 429, 502, 503 and 504 with backoff, and honor retry-after when present. It is a whole number of seconds. Do not retry 400, 401, 402, 404 or 413 until you fix the cause. See Rate limits.