Error Handling
The error envelope, the full status-code reference, and the recovery strategy for every failure mode.
Updated Aug 2026
The API surfaces failures as structured JSON rather than unstructured text. Every non-2xx response shares one envelope, so a client can parse error.code, decide on a recovery path, and attach request_id to a support ticket without inspecting response bodies by hand.
Error envelope
All errors return a body shaped like the one below. The code field is a stable machine-readable string that rarely changes; the message is human-readable and may be refined between releases without breaking clients.
{
"error": {
"code": "invalid_request_error",
"message": "The request body is not valid JSON.",
"request_id": "req_4b8d2e1f7a6c5d9b0e3f2a1c8d7b6e5f"
}
}Status code reference
The table below lists every status code the API emits, the error.code that accompanies it, and the recommended handling.
| HTTP | code | Meaning | Handling |
|---|---|---|---|
| 400 | invalid_request_error | Malformed JSON or an invalid parameter value | Validate payloads before sending; fix and resend |
| 401 | authentication_error | Missing, revoked, or malformed key | Confirm the Bearer header and reissue the key |
| 402 | insufficient_quota_error | Monthly call or token allowance exhausted | Top up the plan or wait for the next cycle |
| 403 | permission_error | Key lacks scope, or source IP not allowlisted | Check key scopes and the IP allowlist |
| 404 | not_found_error | Unknown endpoint or model id | Confirm the path and model id |
| 409 | idempotency_conflict | Retry reuses an Idempotency-Key with a different body | Keep the body stable for a given idempotency key |
| 422 | validation_error | Body is well-formed JSON but fails schema checks | Read the message and correct the offending field |
| 429 | rate_limit_error | RPM or concurrency limit exceeded | Back off exponentially and honor Retry-After |
| 500 | internal_error | Unexpected platform fault | Retry with backoff; escalate with request_id if persistent |
| 503 | service_unavailable | Model temporarily overloaded or updating | Retry after a short delay; check the status page |
Retrying safely
Only a subset of status codes should be retried automatically. Retrying a 400 or 422 replays the same invalid payload and will fail again, while retries of a 500 or 503 are usually productive after a short wait.
- Retry 429, 500 and 503 with exponential backoff and jitter.
- Do not retry 400, 401, 402, 403, 404, 409 or 422 — fix the cause instead.
- Attach the same Idempotency-Key across retries so at-least-once delivery never double-executes.
Correlating failures
The request_id is emitted on every response, success or failure, and is the primary key for support investigation. Log it alongside the request for any call that matters, and include it when reporting an issue.
Was this helpful?
Your feedback shapes how we improve this documentation.