Errors
Errors
Errors use standard HTTP status codes and the OpenAI error envelope, so the SDKs raise the exception classes you already handle. error.param names the offending field when there is one.
Response
{
"error": {
"message": "Invalid API key provided",
"type": "authentication_error",
"param": null,
"code": "invalid_api_key"
}
}| Status | Type | Meaning | What to do |
|---|---|---|---|
400 | invalid_request_error | A parameter is missing, malformed or outside its range. error.param names it. | Fix the request. Retrying will not help. |
401 | authentication_error | Missing, malformed, disabled or unknown API key. | Check the Authorization header and the key's status. |
402 | insufficient_quota | The account has no credit left for this request. | Top up. Do not retry — the balance will not change on its own. |
403 | permission_error | The key or tier may not use this model, endpoint or SDK. | Use a model your tier allows, or a key with the right scope. |
404 | not_found_error | No such model, job or asset. | Check the id against GET /v1/models. |
408 | timeout_error | The generation exceeded the budget for this request. | Retry, or ask for a shorter output. |
409 | invalid_request_error | An Idempotency-Key was reused with a different body, or a job is already in flight. | Use a new key, or resend the identical body. |
413 | invalid_request_error | The upload or request body is over the limit. | See file size limits. |
422 | invalid_request_error | The request is well formed but the values cannot be served together. | Read the message; it names the conflict. |
429 | rate_limit_error | Requests per minute, tokens per minute, a daily cap, or too many concurrent requests. | Back off for Retry-After seconds. See rate limits. |
500 | server_error | An unexpected fault in the gateway. | Retry with backoff. Quote X-Request-Id if it persists. |
501 | server_error | The provider adapter does not implement this capability for this model. | Use a different model for that modality. |
502 | provider_error | The upstream provider returned something unusable. | Retry; routing will usually pick a different provider. |
503 | service_unavailable | No provider can serve this model right now, or the gateway is shedding load. | Retry with backoff, or use another model. |
504 | timeout_error | The upstream did not answer in time. | Retry. |
Handling them
import openai try: response = client.chat.completions.create(model="gpt-5.5", messages=msgs) except openai.RateLimitError as e: # 429 — honour Retry-After rather than retrying immediately. wait = int(e.response.headers.get("retry-after", 60)) except openai.APIStatusError as e: if e.status_code == 402: # Out of credits — top up, do not retry. ... print(e.status_code, e.body["error"]["code"])
Retry 429, 500, 502, 503 and 504. Do not retry 400, 401, 402, 403, 404 or 409. The first group is transient; the second will keep failing until something on your side changes. Errors raised after a stream has started arrive as an error frame inside the stream, because the HTTP status was already sent.
Getting help. Every error response carries
X-Request-Id. Quote it and we can find the exact request — without it, we cannot.