Errors
Gateway errors carry a stable code to branch on and a source saying whether Gateway or the upstream vendor failed. Under a routing policy, Gateway already retries some failures on another route, so read what fails over before adding client retries.
The error envelope
Model endpoints (/v1/responses, the SDK-compatible surfaces, embeddings, media, and batches) return:
Rejections before Gateway reads the body (authentication, budgets, rate limits, blocklist rules, model access, prompt injection, and DLP) send only type, message, and usually code, so read param, source, and provider defensively. Schema validation failures on native POST /v1/responses return 422 with a detail array instead of error.
The Retry column says whether resending the same request can succeed: “Yes” means back off and resend, “No” means change the request or your configuration first.
Invalid requests: 400
Model and routing
Scope
Request body
Tools and web search
Fusion and images
Vendor-reported
Authentication: 401
Payment and budgets: 402
All have type: budget_exceeded except payment_failed. Gateway checks them before calling any vendor.
Every response carries the budget headers for limits that exist: X-Credit-Balance-USD, X-Budget-Limit-USD, X-Project-Budget-Remaining-USD, X-Project-Budget-Limit-USD, X-Key-Limit-Remaining-USD, and X-Key-Limit-USD. X-Budget-Warning, X-Project-Budget-Warning, and X-Key-Limit-Warning appear near a limit. Customer API keys don’t get organization or project headers.
Blocked by policy: 403
A block on the requested model has type: blocked_by_policy. When every model in a routing policy is blocked, the same codes come with type: permission_error.
Not found: 404
Too large: 413
Blocked by guardrails: 422
The body also carries guardrails when you set include_guardrails_metadata.
Rate limited: 429
See Rate limits.
Gateway and vendor failures: 5xx
Batches
Batch endpoints use the same envelope. Line-level errors name the custom_id.
Management and platform APIs
The Management API, the Embedded Routing Stack API, the Evals API, and the Migrations API return {"detail": ...}. Most have a string detail and a standard status: 400 validation, 401 missing or invalid key, 403 missing scope, 404 not found, 409 conflict, 422 schema. Cases worth branching on carry {"detail": {"code", "message"}}:
What fails over
Under a routing policy, vendor 429, 5xx, timeouts, billing errors, vendor 404, output_budget_exhausted, and content-policy refusals move to the next route instead of reaching you, so client retries on them usually repeat work. Gateway’s own 400 to 404, credential 401 and 403, and budget 402 stop (failover rules).
Three kinds of 200 response also fail over, on non-streaming requests only:
When every route returns one of these, you get the last response rather than an error. Each attempt is billed at the route that ran it.
Errors during streaming
If Gateway rejects a streamed request or the vendor’s first frame is an error, you get the same HTTP status and body as a non-streaming request, with no stream. Once the stream opens the status is 200, and failures arrive as frames: response.error on native /v1/responses, error then response.failed on /v1/openai/responses, and an error event on the Anthropic surface.
Requests that run with changes, such as a dropped tool or a clamped effort level, succeed with a warnings array.