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 hello@routergrowth.com.
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 |
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 | no offer fits under routing.max_cost |
raise the cap or pick another strategy |
duplicate_request |
409 | conflicting concurrent request | no |
provider_not_available |
409 | no live provider for this capability yet | later |
rate_limited |
429 | too many requests from your key | with backoff |
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: the waterfall already tried the next-best provider before returning an error.
Reading this as an agent? This page as markdown: /docs/api/errors.md · every page: /docs/llms.txt