Reference
Error codes
Errors follow the OpenAI shape — an error object with type, code, message, and param. The canonical code is stable across versions and what your client should branch on.
Error table
| Status | Code | Meaning |
|---|---|---|
| 400 | invalid_request | Malformed JSON, missing required field, bad parameter type. |
| 401 | invalid_key | Key missing, revoked, or out of scope. |
| 402 | insufficient_credits | Top up or enable auto-recharge in the dashboard. |
| 403 | scope_exceeded | Scoped key hit its spend ceiling or model allow-list. |
| 404 | unknown_model | Model ID not found — hit /v1/models for the live list. |
| 409 | idempotency_conflict | Same idempotency-key with a different body payload. |
| 413 | payload_too_large | Upload exceeded 100MB or message history exceeded model context. |
| 422 | unsupported_parameter | Model doesn't support a parameter you sent (non-fatal warning). |
| 429 | rate_limited | Read the retry-after header — see Rate limits. |
| 499 | client_closed | Client disconnected mid-stream. No charge for uncompleted tokens. |
| 500 | internal_error | Gateway-level fault. Include the request id when reporting. |
| 502 | provider_unavailable | We auto-failover; only surfaces if all fallbacks fail. |
| 503 | capacity_exceeded | Global capacity hit — backoff + retry with jitter. |
| 504 | provider_timeout | Upstream didn't respond in the configured budget. |
Request IDs
Every response (success or error) carries x-request-id. Include it when you ask for help — it unlocks the full upstream trace in support tooling.
Retry strategy
Do retry on 429, 502, 503, 504 with exponential backoff (start 250ms, double on each attempt, jitter ±20%). The SDKs do this by default. Don't retry on 400, 401, 402, 403, 404, 409, 413, 422 — the request is broken and will fail again.