Errors
Stable error codes, HTTP statuses, the error envelope and retry guidance.
Every error, from any endpoint, uses one envelope with a stable, enumerable code:
{
"error": {
"code": "insufficient_balance",
"message": "Top up your wallet to run this call.",
"request_id": "req_1f2e...",
"details": {"optional": "structured context"}
}
}
Branch on code, show message to humans, and include request_id when writing to [email protected].
Codes
| Code | HTTP | Meaning | Retry? |
|---|---|---|---|
invalid_request |
400 | malformed body, unknown field or bad value | fix the request |
invalid_api_key |
401 | missing, malformed or revoked key | no |
invalid_credentials |
401 | bad dashboard sign-in | no |
forbidden |
403 | the key cannot do this (for example: sandbox-only routes on production) | no |
capability_not_found |
404 | unknown capability slug | no; discover first |
endpoint_not_found |
404 | unknown raw endpoint for that provider | no; list /v1/catalog/providers/{provider}/endpoints |
no_match |
404 | providers answered authoritatively: no result | not with the same input |
insufficient_balance |
402 | reservation exceeds available balance | after a top-up |
cost_limit_exceeded |
402 | the run's hold exceeds the workspace's per-run ceiling; the run is blocked |
lower the call or raise the ceiling at /v1/spend-guard |
budget_exceeded |
402 | the daily spend guard would be breached; the run is blocked |
after the UTC reset, or raise the cap |
duplicate_request |
409 | conflicting concurrent request | no |
not_found |
404 | no such route | no |
payload_too_large |
413 | request body above 1 MB | with a smaller body |
provider_not_available |
409 | no live provider for this capability yet, or a provider not exposed raw | later |
rate_limited |
429 | too many requests from your client (counted per key, with a wider cap shared by every key on one IP; per IP for calls without a key, and tighter on sign-in, code requests and OAuth registration); Retry-After says when |
after Retry-After |
provider_rate_limited |
429 | the upstream provider throttled us | with backoff |
provider_error |
502 | the upstream provider failed; nothing charged | yes, with an Idempotency-Key |
provider_timeout |
504 | the upstream provider timed out; nothing charged | yes, with an Idempotency-Key |
internal_error |
500 | our fault; nothing charged without settlement | yes, with an Idempotency-Key |
Retrying safely
Retry provider_error, provider_timeout, internal_error and both rate limits with exponential backoff, always resending the same Idempotency-Key: a retry that races a completed run gets the original result back (Idempotent-Replay: true) instead of a second charge.
On auto routing, most provider failures never reach you: a rate-limited or 5xx provider is retried once after a short wait, and the waterfall tried the next-best provider before returning an error. When max_cost kept a fallback from running, the error message names it and the cap that admits it: raise the cap once rather than resubmitting the same call.
Reading this as an agent? This page as markdown: /docs/api/errors.md · every page: /docs/llms.txt