Reference

Errors

Every error type the API returns, its HTTP status, and how to handle it.

Error shape

Every error, from every endpoint, is a JSON object with a single error key and an HTTP status that matches its type. Branch on type; messages are written for humans and may change.

Example
HTTP/1.1 400 Bad Request
content-type: application/json; charset=utf-8
x-request-id: req_01K58ZX9C4E6G8J1L3N5Q7S9V2

{
  "error": {
    "type": "invalid_request",
    "message": "Invalid request at \"messages.0.role\": Invalid input.",
    "request_id": "req_01K58ZX9C4E6G8J1L3N5Q7S9V2",
    "param": "messages.0.role"
  }
}
FieldTypeDescription
error.typestringMachine-readable error type. See Error types.
error.messagestringA human-readable explanation.
error.request_idstring | nullIdentifies the failed call. Include it when contacting support. Also sent as x-request-id.
error.paramstringPresent when a specific field caused the error, e.g. model or messages.0.content.
error.retry_after_secondsintegerPresent when a retry delay applies. Mirrors the retry-after header.

Error types

TypeHTTPWhen it occursRetry
invalid_request400Malformed JSON, Content-Type other than application/json, a body over 2 MB, a field that fails validation (param names it), image inputs, tools sent to a model without tool support, a sandbox runtime that does not match sandbox_id, code over 100 KB, a request the provider rejected as invalid, or a request cancelled by the client.No; fix the request
invalid_api_key401No key was sent, or the key is malformed, unknown, revoked or expired.No; fix the request
unauthenticated401A session-authenticated console endpoint was called without a valid session. Not returned by /v1 endpoints.No; fix the request
budget_exceeded402The reservation would exceed the key's monthly limit or the project's monthly budget, or an agent run's remaining budget cannot cover the next operation.Not until the limit or balance changes
insufficient_balance402The project's available balance is lower than the reservation.Not until the limit or balance changes
forbidden403The key's project is archived, or the operation is not permitted on this deployment (for example development credit in production).No; fix the request
insufficient_scope403The key lacks the scope the endpoint requires.No; fix the request
model_not_allowed403The model is excluded by the project policy or by the key's allowed models.No; fix the request
model_not_found404No model with this ID exists. List models with GET /v1/models.No; fix the request
not_found404The receipt, sandbox configuration or other resource does not exist or belongs to another project, or no endpoint exists at the requested /v1 path. List endpoints with GET /v1.No; fix the request
method_not_allowed405The endpoint exists but does not accept this HTTP method, for example GET /v1/chat/completions. The allow header lists the supported methods.No; fix the request
conflict409The operation conflicts with the current state of a resource (console operations).No; fix the request
rate_limit_exceeded429The key's or the project's requests-per-minute limit was reached.After retry-after (when present)
internal_error500An unexpected failure inside the platform. The message is always generic.Yes, with exponential backoff
provider_error502The upstream provider failed or could not be reached.Yes, with exponential backoff
sandbox_error502The sandbox node could not be reached, rejected the request, returned a response that failed authentication or was malformed, or sandboxes are not configured on the deployment.Yes, with exponential backoff
service_unavailable503The model is unavailable or its provider is not configured on this deployment, sandbox capacity is temporarily exhausted (retry-after: 5), or a dependency such as onchain purchases is not configured.After retry-after (when present)
provider_timeout504The upstream provider did not respond within the gateway timeout (120 seconds by default).Yes, with exponential backoff

Retries

  • 429 and 503: wait for the number of seconds in retry-after when it is present, then retry.
  • 500, 502 and 504: retry with exponential backoff and jitter, and cap the number of attempts.
  • 402: do not retry in a loop. Add credit, raise the limit, or lower the request's maximum.
  • Other 4xx: the request itself must change. Retrying the same request returns the same error.
retry.ts
async function withRetry<T>(call: () => Promise<Response>, parse: (r: Response) => Promise<T>): Promise<T> {
  const retryable = new Set([429, 500, 502, 503, 504]);
  for (let attempt = 0; ; attempt++) {
    const response = await call();
    if (response.ok) return parse(response);
    if (!retryable.has(response.status) || attempt === 4) {
      const { error } = await response.json();
      throw new Error(`${error.type}: ${error.message} (${error.request_id})`);
    }
    const retryAfter = Number(response.headers.get("retry-after"));
    const delayMs = retryAfter > 0 ? retryAfter * 1000 : Math.min(30_000, 500 * 2 ** attempt) * (0.5 + Math.random());
    await new Promise((resolve) => setTimeout(resolve, delayMs));
  }
}

Errors in streams

Errors detected before a stream opens are returned as ordinary JSON responses with an HTTP error status. After the stream has started (HTTP 200), errors arrive in-band: as a data: event containing error for Chat Completions, or as an error event for Responses. See Chat Completions.

Billing on errors

  • Errors raised before execution (authentication, validation, policy, rate limits, budgets, balance) are never billed.
  • Upstream and sandbox-node failures release the reservation in full and issue no receipt, except when a stream had already delivered output. That portion is billed and receipted with status failed.
  • A sandbox program that exits with an error, or times out, did run: it is billed and receipted.

What errors never contain

Error messages are written for API consumers. They never contain upstream provider credentials, raw upstream error bodies, internal stack traces or database details. Unexpected failures are logged internally against the request ID and returned as a generic internal_error.