Rate limits & errors
Rate-limit headers, backoff for 429, and the error table
Limits apply per key and are enforced on both request count and token throughput. Every response carries the current state:
| Header | Meaning |
|---|---|
x-ratelimit-limit-requests | Requests allowed in the current window. |
x-ratelimit-remaining-requests | Requests left in the window. |
x-ratelimit-reset-requests | Seconds until the request counter resets. |
x-ratelimit-limit-tokens | Tokens allowed in the current window. |
x-ratelimit-remaining-tokens | Tokens left in the window. |
x-ratelimit-reset-tokens | Seconds until the token counter resets. |
Exceeding a limit returns 429. Retry after the interval given in the Retry-After header, and add
exponential backoff with jitter so that retries from concurrent workers do not line up:
import random
import time
import openai
def with_retries(fn, attempts=5):
for attempt in range(attempts):
try:
return fn()
except openai.RateLimitError as err:
if attempt == attempts - 1:
raise
retry_after = getattr(err, "response", None)
delay = float(retry_after.headers.get("Retry-After", 0)) if retry_after else 0
time.sleep(max(delay, 2**attempt) + random.random())The official OpenAI SDKs already retry 429 and 5xx a couple of times. Set max_retries when
constructing the client if you want different behavior, and reserve custom logic for cases the SDK
does not cover.
Errors
Failures use conventional HTTP status codes with a consistent body:
{
"error": {
"message": "Human-readable description of what went wrong.",
"type": "invalid_request_error",
"code": "context_length_exceeded"
}
}| Status | Meaning | What to do |
|---|---|---|
400 | Malformed request or an unsupported parameter | Fix the request. Retrying will not help. See models & parameters. |
401 | Missing or invalid key | Check the Authorization header. See keys & authentication. |
403 | Key has no access to this model | Request access or pick another model. |
404 | Unknown endpoint or retired model | Re-check the path and GET /v1/models. |
429 | Rate limit or quota exhausted | Back off and retry, or raise your limit. Quota is on usage & billing. |
5xx | Upstream or gateway failure | Retry with backoff. |
Log error.code rather than matching on error.message — the code is stable, the message is not.