LLM API Errors and Rate Limits Explained: 401, 403, 429 and 529 for OpenAI, Claude and Gemini (2026)
On this page
Short answer:
- 401 means your API key is wrong or missing.
- 403 means you're not allowed: a region block, permissions, or an IP allowlist.
- 429 means either a rate limit (slow down and retry) or an exhausted quota or spend cap (add credit; retrying won't help). Read the error code to tell which.
- 5xx and 529 are on the provider's side. Retry with backoff.
Below are the exact messages each provider returns, how their rate limits work, and a retry pattern we tested.
The same error, three providers
We sent requests with an invalid key to each provider on October 15, 2026:
| Provider | Status | What came back |
|---|---|---|
| OpenAI | 401 | Incorrect API key provided: sk-inval****ting … · code invalid_api_key |
| OpenAI (no key) | 401 | Missing bearer or basic authentication in header |
| Anthropic | 401 | invalid x-api-key · type authentication_error |
| Anthropic (no key) | 401 | x-api-key header is required |
| Gemini (OpenAI-compatible endpoint) | 400 | Please pass a valid API key · status INVALID_ARGUMENT |
Gemini signals a bad key with 400, not 401. Error handlers that only treat 401 as "auth failed" will misclassify it.
Error codes by status
| Status | OpenAI | Anthropic (Claude) | What to do |
|---|---|---|---|
| 400 | invalid_request_error: malformed request |
invalid_request_error, also returned when a spend limit you set is reached |
Fix the request. Don't retry |
| 401 | Incorrect API key provided, Invalid Authentication, IP not authorized |
authentication_error: bad, revoked or expired key |
Check the key and header |
| 402 | — | billing_error |
Fix payment details |
| 403 | Country, region, or territory not supported |
permission_error: the key lacks access to that resource |
Region or permission issue. Retrying won't help |
| 404 | Unknown path or model | not_found_error |
Check the endpoint and model ID |
| 413 | — | request_too_large |
Shrink the request |
| 429 | Rate limit, slow_down, or billing codes (see below) |
rate_limit_error: rate limit, acceleration limit, or monthly spend cap |
See the next section |
| 500 | Server error | api_error |
Retry with backoff |
| 503 | server_is_overloaded |
— | Retry after Retry-After |
| 504 | — | timeout_error |
Use streaming for long requests |
| 529 | — | overloaded_error: Anthropic-wide overload |
Retry with backoff |
429: rate limit or out of money?
The status code is the same, but the fix is the opposite.
OpenAI: read error.code.
error.code |
Meaning | Fix |
|---|---|---|
(rate limit) / slow_down |
Too many requests or tokens, or traffic ramped too fast | Back off, follow Retry-After, ramp up gradually |
credit_balance_exhausted |
No prepaid credits left | Add credits |
organization_spend_limit_exceeded / project_spend_limit_exceeded |
A spend limit you set was hit | Raise or remove the limit |
organization_usage_limit_exceeded |
Your tier's usage limit was hit | Request a higher limit |
OpenAI's docs are explicit: retrying billing, spend or quota errors won't restore access.
Anthropic: a normal rate-limit 429 usually carries a retry-after header. The monthly spend-cap 429 never does. It says your organization "has crossed its monthly API usage threshold" and keeps failing until the 1st of next month (UTC) or until you move up a tier. A sudden traffic spike can also trigger acceleration limits. Ramp up gradually.
Gemini: limits are enforced per project as RPM, TPM and RPD, plus spend-based limits over a rolling 10-minute window on paid tiers ($10 per 10 minutes on Tier 1, $50 on Tier 2, $200 on Tier 3). Exceeding them returns 429 RESOURCE_EXHAUSTED.
How each provider's rate limits work
| OpenAI | Anthropic (Claude) | Google Gemini | |
|---|---|---|---|
| Measured in | Requests and tokens per minute (per model), with optional project token limits | Requests/min, input tokens/min and output tokens/min, per model class | Requests/min, tokens/min, requests/day (per model) |
| Scope | Organization and project | Organization (workspaces can set lower limits) | Project, not per key |
| Tiers | Free → Build ($5 purchased) → Launch ($100) → Grow ($500) | Evaluation → Start → Build → Scale, with monthly spend caps of $500 / $1,000 / $200,000 | Free → Tier 1 (billing linked) → Tier 2 ($100 paid) → Tier 3 ($1,000 paid) |
| Where to see yours | Settings → Organization → Limits | Console → Rate limits | AI Studio → Rate limit |
| Response headers | x-ratelimit-remaining-requests, x-ratelimit-remaining-tokens, x-ratelimit-reset-*, Retry-After |
anthropic-ratelimit-requests-remaining, anthropic-ratelimit-input-tokens-remaining, …-reset, retry-after |
— |
| Worth knowing | slow_down means you ramped traffic too fast |
Limits refill continuously (token bucket). Cached input tokens don't count toward input tokens/min on most models | Daily limits reset at midnight Pacific. Preview models get tighter limits |
The Claude caching detail is easy to miss and very useful. With a 2,000,000 input-tokens-per-minute limit and an 80% cache hit rate, Anthropic's docs show you can process about 10M total input tokens a minute, because cache reads don't count. Caching raises throughput as well as cutting cost (see Claude API pricing).
Retry the right way
First, use the SDK's built-in retries. The official OpenAI and Anthropic SDKs already retry connection errors, 429s and 5xx responses with exponential backoff, twice by default, and honor retry-after. Raising max_retries is often all you need:
from openai import OpenAI
client = OpenAI(max_retries=5)
If you need control (for example, to stop immediately on billing errors), here's a pattern we tested with openai 3.31.0:
import time
from openai import OpenAI, APIStatusError, APIConnectionError
client = OpenAI(max_retries=0) # we handle retries ourselves
RETRY_STATUS = {429, 500, 502, 503, 504, 529}
# Quota and spend-limit errors also arrive as 429, but retrying won't fix them.
NO_RETRY_CODES = {"insufficient_quota", "credit_balance_exhausted",
"organization_spend_limit_exceeded", "project_spend_limit_exceeded"}
def create_with_retry(attempts=5, **kwargs):
delay = 1.0
for attempt in range(1, attempts + 1):
try:
return client.chat.completions.create(**kwargs)
except APIStatusError as e:
if e.status_code not in RETRY_STATUS or e.code in NO_RETRY_CODES or attempt == attempts:
raise
wait = float(e.response.headers.get("retry-after") or delay)
except APIConnectionError:
if attempt == attempts:
raise
wait = delay
time.sleep(wait)
delay = min(delay * 2, 30)
Running it with an invalid key raised the 401 immediately, without retrying. That's what you want: auth, permission and validation errors fail the same way every time. If many workers retry at once, add a little random jitter to wait so they don't all hit the API in the same second.
Errors through an API gateway
If you call models through a gateway or proxy, an error can come from the gateway (your gateway key, balance or model name) or be passed through from the upstream provider. The body usually tells you which. For example, api.foo, the gateway behind these docs, returns:
{"error":{"code":"","message":"Invalid token (request id: …)","type":"new_api_error"}}
type: new_api_error and the gateway's own request ID mean the gateway rejected the request before it reached any model provider. (api.foo shows the message in Chinese unless the request includes Accept-Language: en.) Messages without that wrapper usually came from the upstream provider.
Debugging checklist
- Log the status code, the full error body and the request ID. OpenAI returns an
x-request-idheader, Anthropic includesrequest_idin the body, and most gateways include their own. - Check the base URL and path. A doubled
/v1/v1or a missing/v1produces a 404. - Check the model ID against the provider's current list. Models get renamed and retired.
- Check where you are calling from. A 403 "country not supported" is about location, not the key.
- Check billing pages before retrying 429s, to make sure it's actually a rate limit.
Related
FAQ
What does a 429 error mean on the OpenAI or Claude API?
Either you're sending requests or tokens faster than your rate limit allows, or your account has run out of credit or hit a spend cap. On OpenAI, check error.code (credit_balance_exhausted or *_spend_limit_exceeded mean billing). On Claude, a spend-cap 429 has no retry-after header. Billing-type 429s won't clear by retrying.
What is a 529 error from the Claude API?
overloaded_error. Anthropic's API is temporarily overloaded across all users. Retry with exponential backoff. It isn't caused by your account or your limits.
Why does Gemini return 400 instead of 401 for a bad API key?
Gemini reports an invalid key as INVALID_ARGUMENT ("Please pass a valid API key") with HTTP 400, including through its OpenAI-compatible endpoint. Treat that message as an authentication failure in your error handling.
How do Claude API rate limits work?
Per model class, as requests per minute, input tokens per minute and output tokens per minute, using a token bucket that refills continuously. For most models only uncached input tokens count toward the input limit, so prompt caching raises effective throughput.
Should I retry API errors automatically?
Retry 429 rate limits, 5xx errors and 529 overloads with exponential backoff, honoring the Retry-After header. Don't retry 400, 401, 403 or 404, or billing and quota errors, because the same request will fail again.
Found a mistake? Email [email protected].