Errors
Status codes, error types and the fix for each.
Reference / errors
Errors share one JSON shape. Branch on error.type and show message to people. A refused 402 also carries the zero-cost receipt the gateway signed for the refusal, so the breaker trip is provable too.
json
{
"error": {
"type": "cap_reached",
"message": "This key reached its spend cap. The gateway refused the call before it reached a model.",
"receipt": { "id": "req_...", "receipt": "eyJ...", "signature": "0x...", "signer": "0x...", "payload": { "status": "cap_reached", "cost_micro_usd": 0 } }
}
}| Status | Type | Meaning | Fix |
|---|---|---|---|
| 400 | invalid_request | The body or a parameter is malformed. | Correct the request before you send it again. |
| 401 | invalid_key | The key is missing or unknown. | Check the Authorization header. |
| 402 | cap_reached | The key hit its spend cap. Nothing went upstream. | Raise the cap in the dashboard, or wait for a day or month window to roll over. |
| 402 | insufficient_balance | The balance can't cover the call. | Top up with ETH on Robinhood Chain. |
| 403 | model_not_allowed | The model isn't on the key's allowlist. | Call an allowed model or edit the key. |
| 403 | key_expired | The key passed its expiry. | Create or delegate a new key. |
| 403 | key_revoked | You revoked the key or its parent. | Switch to another key. |
| 413 | code_too_large | The submitted code is over the size limit. | Send a smaller program. |
| 429 | rate_limited | Too many requests for the key, or for your IP on Terminal. | Back off and retry. |
| 502 | upstream_error | The upstream model host returned an error. | Retry, or try another model. |
| 503 | upstream_unavailable | The gateway can't reach the upstream. | Check GET /v1/status and retry later. |
Retrying
Retry 429, 502 and 503 with backoff. A 400, 401, 402 or 403 returns the same error until you change the request, the key or the balance.