Rate limits & errors
Understand rate-limit policies, retries, and the gateway error contract.
RouteMux applies its own rate-limit policy on top of upstream provider limits. The policy governs requests per minute and concurrent streams per account, and is resolved per request — your key's policy first, then your account's, then the platform default.
Handling 429
When you exceed a limit, the gateway returns
LIMIT_RATE_EXCEEDED with HTTP 429 in the error
shape of the entry protocol.
{
"error": {
"code": "LIMIT_RATE_EXCEEDED",
"message": "A RouteMux request, concurrency or policy limit was reached. Honor Retry-After and retry with exponential backoff and jitter.",
"reference": "RMX-LIMIT-4001",
"documentation_url": "https://routemux.com/docs/errors#rmx-limit-4001",
"request_id": "req_01K0EXAMPLELIMIT",
"retry": { "retryable": true, "strategy": "BACKOFF" },
"billing": { "status": "NOT_BILLED" }
}
}Back off and retry
Treat 429 as transient. Retry with exponential backoff and jitter rather than
hammering the endpoint. If you consistently hit limits, contact support about a
higher policy tier.
Error shape per protocol
Errors are returned in the shape of the family you called, so your existing SDK error handling keeps working:
/v1/*and/responses— OpenAI error shape./anthropic/*and/v1/messages— Anthropic error shape./vertex-ai/*— Gemini / Google error shape.
Gateway error reference
| Error | HTTP | Meaning |
|---|---|---|
AUTH_API_KEY_REQUIRED | 401 | No API key was sent. |
AUTH_INVALID_API_KEY | 401 | Key does not exist or cannot be validated. |
AUTH_AMBIGUOUS_API_KEY | 400 | Different credentials were sent in multiple key headers. |
AUTH_API_KEY_INACTIVE | 403 | The key exists but is disabled. |
AUTH_API_KEY_EXPIRED | 403 | The key is past its expiry date. |
LIMIT_API_KEY_QUOTA_EXHAUSTED | 429 | The key hit its configured quota. |
AUTH_ACCOUNT_SUSPENDED | 403 | The owning account cannot make requests. |
BILLING_INSUFFICIENT_CREDITS | 422 | Wallet balance is insufficient. |
LIMIT_RATE_EXCEEDED | 429 | RPM, concurrency, or policy limit hit. Honor Retry-After. |
MODEL_NOT_FOUND | 404 | No such model in the catalog. |
MODEL_PROTOCOL_UNSUPPORTED | 400 | Model doesn't support that protocol. |
MODEL_NOT_PROVISIONED | 503 | The model is not enabled yet. Retrying unchanged will not help. |
MODEL_BUSY | 503 | The model is at capacity. Retryable; honor Retry-After. |
MODEL_UNAVAILABLE | 503 | The selected model could not serve the request. |
Idempotency
Send an X-Idempotency-Key header to make a request safe to retry:
curl https://api.routemux.com/v1/chat/completions \
-H "Authorization: Bearer $ROUTEMUX_API_KEY" \
-H "X-Idempotency-Key: idem_2026_06_19_001" \
-H "Content-Type: application/json" \
-d '{ "model": "openai/gpt-4o-mini", "messages": [{ "role": "user", "content": "hi" }] }'- If a request with the same key is still in flight, you get
IDEMPOTENCY_IN_PROGRESS(409) and the upstream is not called again. - If it already completed, you get
IDEMPOTENCY_REPLAY_UNAVAILABLE(409) — the request is not re-billed, but the original response body is not replayed.
Idempotency keys are scoped to your account and prevent double-billing across retries and reconciliation.