Skip to main content
Every failure returns one JSON object with a stable shape, an explicit retryable boolean, and, where a fix exists, a machine-executable way out. This is a real rejection from the live gateway, unedited:
retryable: false means the same request will never succeed; fix it instead. details names the exact parameter, what you sent, and what was allowed. recovery is a corrected call an agent can execute verbatim. request_id is safe to share with support. Error responses never charge data credits, though they do spend a rate unit.

Gateway codes

The table reflects current gateway behavior; the retryable boolean in the payload is always the authority.

Data-shaped codes

The engine also refuses at the level of the question itself. These arrive in the same envelope; branch on the retryable boolean the payload carries. A whole operation that cannot prove its primary answer errors like this rather than returning a hollow success. Partial gaps inside an otherwise provable response use the unavailable block instead; that split is defined in the data contract.

What to do

Fix the request for the non-retryable codes: correct parameters against schema, resolve ambiguous symbols, check the key, fund the balance. Retry the retryable codes with backoff, honoring Retry-After where it is sent. Reusing the same idempotency key on those retries is safe: any transient 408, 425, 429, or 5xx releases the idempotency hold, so the retry executes fresh and settles once. internal_error is deliberately not marked retryable because success is not expected; a retry is safe but not promising, so capture the request_id instead.

Deadlines and limits

The gateway uses a 15-second upstream deadline and a 2 MiB response limit. A request that exceeds the deadline returns timeout. When a response would be too large for the service to serve, response_too_large says so; narrow the request with limit, fewer statements, or a shorter range.