API
Errors
Error shapes and the full gateway error code table.
Errors use the OpenAI error envelope on every endpoint, so existing SDK error handling keeps working:
json
{
"error": {
"message": "Team budget exhausted: monthly hard cap of $500.00 reached.",
"type": "insufficient_quota",
"code": "budget_exceeded"
}
}Error codes
| HTTP | code | Meaning |
|---|---|---|
| 401 | invalid_api_key | The tr_ key is missing, malformed, revoked, or deleted. |
| 429 | rate_limit_exceeded | Per-key RPM or TPM limit hit. The response includes a Retry-After header — back off and retry. |
| 429 | budget_exceeded | A team, member, or key budget with a hard cap is exhausted for the current window. |
| 429 | monthly_quota_exceeded | Your plan's monthly gateway request quota is used up. Upgrade or wait for reset. |
| 403 | model_not_allowed | The requested model is excluded by your team's model allowlist. |
| 404 | model_not_found | Unknown model ID or alias. |
| 400 | provider_key_missing | No provider key on file for the provider that serves the requested model. |
| 403 | subscription_inactive | Trial ended or subscription lapsed. Update billing in the console. |
| 502 | upstream_error | The provider returned an error or was unreachable. The provider's message is included when available. |
Handling 429s
All three 429 codes are deliberate gateway decisions, not provider throttling. rate_limit_exceeded is transient — honor Retry-After. budget_exceeded and monthly_quota_exceeded will not succeed on retry until the budget window resets or a limit is raised, so treat them as terminal in retry loops.
python
import openai
try:
response = client.chat.completions.create(
model="auto", messages=[{"role": "user", "content": "hi"}]
)
except openai.RateLimitError as e:
code = e.body.get("code") if isinstance(e.body, dict) else None
if code == "rate_limit_exceeded":
... # back off and retry
else:
... # budget/quota exhausted: alert, don't retry