Errors
BetaWe just launched Apps: hosted models, actions and pages, on the same bill as your inference.Read the Apps docs
API reference/Reference/Errors

Errors

Errors use standard HTTP statuses and a stable machine-readable code.

Error shape

{
  "error": {
    "type": "billing_error",
    "code": "insufficient_balance",
    "message": "Available balance 0.02 is below the required reservation 0.05",
    "request_id": "req_6f1c…"
  }
}

Branch on code for the specific case and on type for the kind of thing that went wrong, not on message. Messages may change; codes and types won't. Some errors include param naming the field at fault, such as model or ib.suggestion; a refused record write adds problems, a failed action event and logs. Every error response carries the X-Request-ID header, and request_id matches it: errors are in Logs too, and a request refused before dispatch is never charged.

Categories

type follows from the status, so a client that only needs “my fault, or retry” can branch on it without a table of codes. The names are Anthropic's, so code written for their SDK's error classes carries over.

TypeStatusWhat to do
invalid_request_error400, 409, 422Something in the request: fix it before sending it again.
authentication_error401The key is missing, wrong or revoked.
billing_error402The team can't pay for this request: add credit, or raise the budget.
permission_error403The key, its Directives or the account don't allow it.
not_found_error404No such route or resource.
request_too_large413Shrink the body.
rate_limit_error429Wait for Retry-After, then retry.
overloaded_error503Temporary: retry with backoff.
api_erroranything elseSomething on our side: retry with backoff, and check the receipt first for a request that may have run.

Codes

StatusCodeWhat to do
400invalid_requestFix the request body or parameters.
400unsupported_parameterRemove the parameter, or pick a model that supports it.
400context_limit_exceededInput plus max_tokens is over the model's context window, or the input is over your maxInputTokens Directive. Shorten the input or lower max_tokens.
401invalid_api_keyCheck the key, or create a new one.
402insufficient_balanceAdd credit or turn on auto reload.
402budget_exceededRaise the budget in Directives, or wait for the next period.
403policy_deniedDirectives don't allow the model, its providers, or this request's maximum charge; the project or environment is disabled; or the key lacks a permission the route needs (such as Auditor Permissions). The message says which.
404not_foundNo such route: check the method and path. For an Auditor repository, install the GitHub App on it first.
403account_suspendedContact support.
409idempotency_conflictThe Idempotency-Key was used with a different body. Use a new key.
409request_in_progressThe original request with this key is still running. Wait for it.
409result_not_replayableThe original request finished. Read its receipt instead of retrying. On the management API: the original call already made the key, rotation or webhook endpoint named in original_id; read it there.
409version_conflictDirectives changed since you read them (management API). Read them again, apply your change to the current policy_version, and retry.
413payload_too_largeKeep the body under the endpoint's limit: 1 MiB for inference, 64 KiB for the management API and for changing a repository's Auditor setup, 4 MiB for Review a change.
429rate_limit_exceededYour Directives requests- or tokens-per-minute limit, not an outage. Wait for Retry-After seconds, or raise the limit (see Rate limits below).
429concurrency_limit_exceededYour Directives concurrent-requests limit, not an outage. Wait for an in-flight request to finish, or raise the limit.
429upstream_rate_limitedEvery allowed provider was at capacity. Raising your limits won't help; retry after a short wait.
503no_healthy_routeNo allowed provider is available right now, or the model is temporarily disabled. Retry with backoff.
503dependency_unavailableTemporary platform issue. Retry with backoff.
503upstream_funding_unavailableTemporary platform issue. Retry with backoff.
504request_deadline_exceededThe provider didn't answer in time. Check the receipt before retrying; a generation may have completed. Stream long requests.

Rate limits

A 429 comes from one of two places. rate_limit_exceeded and concurrency_limit_exceeded mean a limit in your Directives was reached; every team has defaults (600 requests and 2,000,000 tokens per minute, 10 concurrent) even if none were set. The X-RateLimit-Scope and X-RateLimit-Dimension headers name the level and the limit, and the message gives its value. upstream_rate_limited means the providers themselves were at capacity. Neither kind is charged.

Errors during a stream

Once a stream has started, the status is already 200 and can't change. If it fails partway, a last event carries the error and the stream closes without a [DONE] marker:

data: {"error":{"type":"api_error","code":"stream_interrupted","message":"…"}}

Treat a stream without [DONE] as incomplete, and don't stitch output from separate requests together. The receipt still records what the provider billed for the partial answer.

Anthropic Messages

/v1/messages returns errors in Anthropic's layout, { "type": "error", "error": { "type", "code", "message" }, "request_id" }, so Anthropic SDKs handle them natively: the same type and code as above, with request_id at the top level instead of inside error. A stream that breaks ends with an event: error frame instead of a missing [DONE].

OpenAI Responses

/v1/responses returns errors in the shape above. A stream that breaks ends with an event: error frame, { "type": "error", "code": "stream_interrupted", "message" }, and no response.completed.