Reference
Rate limits
Sixty requests a minute per key, the headers that tell you where you stand, and how to back off correctly.
60 requests per minute, per API key. Fixed window.
Requests authenticated with a browser session rather than a key — which is the playground, not anything you would write — are limited to 20 per minute per account, separately.
Headers
Every rate-limited response carries all three, including the 429:
| Header | Meaning |
|---|---|
X-RateLimit-Limit | The ceiling for this window |
X-RateLimit-Remaining | What is left |
X-RateLimit-Reset | Unix seconds when the window rolls over |
A 429 also carries Retry-After, in seconds.
Backing off
Read Retry-After and wait. If you are writing your own retry loop, exponential backoff with jitter
on 429 and 502, and no retry at all on 400, 401, 402, 403 or 404 — none of those get
better by being sent again.
import time, random, openai
def with_retry(fn, attempts=5):
for i in range(attempts):
try:
return fn()
except openai.RateLimitError as e:
wait = float(e.response.headers.get("retry-after", 0)) or (2 ** i + random.random())
time.sleep(wait)
except openai.APIStatusError as e:
# 402 means top up, 4xx means fix the request. Neither is helped by retrying.
if e.status_code != 502:
raise
time.sleep(2 ** i + random.random())
raise RuntimeError("still rate limited after retries")The openai SDK already retries 429 and 5xx with backoff by default. Set max_retries on the
client rather than writing your own unless you need something specific.
If you need more
Ask. There is no self-serve tier that raises it, and the limit exists to stop a runaway loop spending a balance in seconds rather than to ration capacity. Tell us what you are building and what rate you need.
What counts
A request counts when it is accepted, including one that then fails at the model. A request refused by the limiter does not consume any of your balance.