Errors and retries
Handle the stable error envelope, rate limits, and idempotent retries.
Most API errors use a consistent envelope:
{
"type": "error",
"error": {
"type": "invalid_request_error",
"message": "The request body is invalid."
},
"request_id": "req_example"
}Log request_id with your own request trace. Do not expose credentials or complete request bodies in client-facing logs.
An application-instruction rejection returns 422 with a public review object instead of a request ID. Use its summary and findings to revise the proposed instructions.
Common status codes
| Status | Meaning | Action |
|---|---|---|
400 | Invalid request | Correct the request before retrying. |
401 | Authentication failed | Replace or rotate the key. |
402 | A configured spend limit was reached | Review limits in the console. |
404 | The resource is unavailable to this key | Verify the ID and project boundary. |
409 | State or idempotency conflict | Reconcile the existing operation before retrying. |
422 | Application instructions were rejected | Revise them before trying again. |
429 | Rate limit exceeded | Wait for Retry-After and use backoff with jitter. |
503 | Retryable processing or provider availability issue | Follow Retry-After; poll request status when a request ID is present. |
Idempotency
For non-streaming message calls, send one stable idempotency_key per logical operation. If a timeout makes the outcome uncertain, retry with the same key instead of creating a second operation.