Error code reference.
Every HTTP status and error.code the gateway returns, what causes it, and how your client should handle it.
Standard error body
Every error response from Anoman is a single JSON object with an error key. The shape matches OpenAI’s error envelope so existing SDK error handling works unchanged.
The type field groups errors into five families; code is the specific machine-readable string you should switch on in client code.
All error codes
Codes are grouped by family. Retryable column tells you whether a retry-with-backoff is the appropriate response.
| HTTP | Code | Type | Cause | Retry? |
|---|---|---|---|---|
| 401 | auth_missing | invalid_request | No Authorization header | No |
| 401 | auth_invalid | invalid_request | Malformed or unknown key | No |
| 403 | auth_revoked | invalid_request | Key was revoked | No |
| 402 | budget_exceeded | billing | Per-key monthly USD cap hit | No |
| 402 | insufficient_credits | billing | Prepaid balance exhausted | No |
| 402 | token_quota_exceeded | billing | Weekly or monthly token cap hit for a model tier class | No |
| 403 | prompt_injection | guardrail | The injection classifier flagged the user content | No |
| 403 | pii_blocked | guardrail | PII detected and policy mode is block | No |
| 403 | content_violation | guardrail | Content moderation blocked the request | No |
| 403 | tool_denied | guardrail | Tool name appears in policy denylist and the group's tool policy mode is Block (Monitor, the default, records the hit and lets the request through) | No |
| 403 | tool_not_allowed | guardrail | Tool not in policy allowlist and the group's tool policy mode is Block (Monitor records it instead) | No |
| 400 | model_not_found | invalid_request | Model slug not in our catalog | No |
| 400 | context_length_exceeded | invalid_request | Prompt + completion exceeds model context window | No |
| 400 | vision_not_supported | invalid_request | Image input passed to a text-only model | No |
| 429 | rate_limit_exceeded | rate_limit | RPM or TPM burst guard tripped | Yes |
| 429 | concurrent_limit_exceeded | rate_limit | Inflight cap reached for this key | Yes |
| 503 | provider_unavailable | provider | All upstream routes failed after retries | Yes |
| 504 | provider_timeout | provider | Upstream did not respond within 120s | Yes |
| 503 | cost_cap_open | provider | Circuit breaker open on the upstream | Yes |
Auth + budget + guardrail errors return immediately and won’t succeed on retry — fix the request or the configuration. Rate limit + provider errors are transient — retry with exponential backoff and respect the Retry-After header.
Reading 403 guardrail errors
When a guardrail blocks a request the response is 403 and the type is guardrail_error. The full guardrail pass/fail breakdown is also exposed on the successful response in the _anoman.guardrails object, see Guardrails.
403 — prompt injection blocked
403 — tool denied by policy (only when the group's tool policy mode is Block)
Guardrail block is the right behavior — don’t silently retry. Either surface to the end user (with a generic refusal message) or escalate to a human review queue if the surface is high-stakes.
Reading 402 and 429 responses
Don’t confuse the spend boundary with the flood guard. 402 token_quota_exceeded means you hit a model tier class’s weekly or monthly token cap — not retryable until the window rolls over (buy a token pack, upgrade, or switch model class). 429 rate_limit_exceeded means an RPM/TPM burst guard filled up, and concurrent_limit_exceeded means too many simultaneous inflight requests — both transient, safe to retry with backoff.
402 — token quota exceeded (model tier class)
429 — RPM burst guard tripped
429 — inflight cap (concurrent requests)
Full per-tier limits + headers reference at Rate limits.
Exponential backoff with jitter
The OpenAI / Anthropic SDKs already retry by default, but the defaults are conservative. Here’s an explicit pattern that respects Retry-After:
Python — robust retry with exponential backoff
TypeScript — robust retry
See guardrails fire on real requests.
The dashboard surfaces every block with the prompt that caused it.