api.foo
api.foo / Docs / API errors & rate limits

LLM API Errors and Rate Limits Explained: 401, 403, 429 and 529 for OpenAI, Claude and Gemini (2026)

Updated · Tested on: Python openai 3.31.0 · live error responses from OpenAI, Anthropic, Google and api.foo
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

  1. Log the status code, the full error body and the request ID. OpenAI returns an x-request-id header, Anthropic includes request_id in the body, and most gateways include their own.
  2. Check the base URL and path. A doubled /v1/v1 or a missing /v1 produces a 404.
  3. Check the model ID against the provider's current list. Models get renamed and retired.
  4. Check where you are calling from. A 403 "country not supported" is about location, not the key.
  5. Check billing pages before retrying 429s, to make sure it's actually a rate limit.

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].