OpenAI "insufficient_quota": 4 causes in diagnostic order

OpenAI's insufficient_quota error (HTTP 429, error code insufficient_quota) means your account has no API credits left to spend. It's critically different from a rate limit: a rate limit is a speed restriction that clears in seconds; insufficient quota means you have no budget and requests will keep failing until you add one. This page covers all four causes and how to fix each.

The 30-second answer

What the error looks like

HTTP/1.1 429 Too Many Requests
{
  "error": {
    "message": "You exceeded your current quota, please check your plan and billing details.",
    "type": "insufficient_quota",
    "param": null,
    "code": "insufficient_quota"
  }
}

The key distinguisher from a rate limit: "code": "insufficient_quota" vs. "code": "rate_limit_exceeded". Rate limits have a Retry-After header and clear on their own. Insufficient quota does not — it persists until you resolve the billing issue.

In the OpenAI Python SDK this raises openai.RateLimitError — confusingly, both rate limits and quota errors use this same exception class. Check error.code in the exception body to distinguish them.

Verified client-side behaviour — 5 September 2026

The billing causes below depend on your OpenAI account and cannot be reproduced from outside it. What can be verified is how the Python SDK behaves when it receives this error, so that part was run rather than assumed. Environment: openai==3.8.0, Python 3.11.15, Linux; a local HTTP server returned the 429 body shown above (OpenAI's documented shape, "code": "insufficient_quota") so no credits were involved.

1. The SDK retries a quota error twice before it tells you. With the default max_retries=2, one chat.completions.create() call produced three HTTP requests (x-stainless-retry-count 0, 1, 2) and took 1.3 s before raising. With max_retries=0 it made one request and raised immediately:

429 insufficient_quota, default max_retries
  -> RateLimitError: Error code: 429 - {'error': {'message': 'You exceeded your current quota, ...
  -> server received 3 request(s), x-stainless-retry-count seen: ['0', '1', '2'], client gave up after 1.3s

429 insufficient_quota, max_retries=0
  -> RateLimitError: Error code: 429 - {'error': {'message': 'You exceeded your current quota, ...
  -> server received 1 request(s), x-stainless-retry-count seen: ['0'], client gave up after 0.0s

A quota error never clears on retry, so those retries are pure waste — and in a loop or a batch job they triple the volume of 429s in your logs and dashboards. That is why a single exhausted account can look like a rate-limit storm.

2. Exactly which fields distinguish it from a real rate limit. Both arrive as openai.RateLimitError. On the quota error the exception carried e.status_code == 429, e.code == "insufficient_quota", e.type == "insufficient_quota". In the same test a 429 carrying "code": "rate_limit_exceeded" and a Retry-After: 1 header was also retried twice, and the SDK waited the header's delay each time (2.0 s total) — correct behaviour for a real rate limit, wasted time for a quota error. So branch on e.code, not on the class:

from openai import OpenAI, RateLimitError

client = OpenAI(max_retries=0)   # stop the SDK from retrying a non-retryable error
try:
    r = client.chat.completions.create(model="gpt-4o-mini", messages=[{"role": "user", "content": "hi"}])
except RateLimitError as e:
    if e.code == "insufficient_quota":
        raise SystemExit("Out of API credit - fix billing, do not retry")   # this is a billing problem
    # any other 429 is a real rate limit: back off and retry
    ...

3. The dashboard URLs and free-credit rules below were not re-verified on this date (they require a signed-in account). Treat the exact menu paths as approximate; the diagnostic order is what matters.

Cause 1: No payment method on the account

New OpenAI accounts get a small amount of free API credits. Once those are exhausted, you must add a payment method to continue. Many developers don't realize the free credits ran out until they get this error.

Fix:

  1. Go to platform.openai.com/settings/organization/billing.
  2. Under Payment methods, add a credit card.
  3. Purchase credits or enable auto-recharge.
  4. Wait 5–10 minutes for the quota to activate — changes are not instant.
  5. Test with a minimal API call to confirm access is restored.

Cause 2: Monthly spend limit reached

OpenAI lets you set a monthly spend limit as a cost control. When your API usage hits that limit, all further requests return insufficient_quota for the rest of the calendar month — even if your payment method is valid and has available credit.

Fix:

  1. Go to platform.openai.com/settings/organization/limits.
  2. Check "Monthly budget" and compare it to your current month's usage in the usage dashboard.
  3. If you've hit the limit, either increase the monthly budget or wait for the month to reset.
  4. Note: the spend limit resets on the 1st of each calendar month, not on your billing anniversary.

Cause 3: Project-level spend limit (project API keys)

OpenAI's newer account structure uses Projects, each with their own API keys and optional spend limits. If you're using a project key (format: sk-proj-...), the quota error may be at the project level even if the organization has remaining budget.

Fix:

  1. Go to platform.openai.com → Your project → Settings.
  2. Check "Monthly spend limit for this project."
  3. Increase the project limit or switch to using an organization-level key for testing.

Note: organization-level API keys (format: sk-... without "proj") use the org's total budget. Project keys are capped at the project limit, which can be lower. If you're unsure which type your key is, check the prefix.

Cause 4: Free tier credits expired

OpenAI's free API credits expire 3 months after account creation. After expiry, any API call returns insufficient_quota until a payment method is added — even if you didn't use all the free credits before they expired.

Check if this is your situation:

Fix: same as Cause 1 — add a payment method. Free credits can't be restored or extended once expired.

How to verify quota is restored after fixing

# Quick test — minimal token usage:
curl https://api.openai.com/v1/chat/completions \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-5.4-mini",
    "messages": [{"role": "user", "content": "Hi"}],
    "max_tokens": 5
  }'

# A successful response (HTTP 200) means quota is restored.
# Still getting 429 with insufficient_quota? Wait another 5 minutes —
# billing changes take time to propagate.

FAQ

Does insufficient_quota reset at the end of the month? Only if you hit the monthly spend limit (Cause 2). If the cause is no payment method or expired free credits, there's no monthly reset — you need to add a payment method.

Can I check my remaining quota via the API? No — OpenAI doesn't expose remaining quota through the API. You have to check the usage dashboard at platform.openai.com/usage. There are third-party tools that estimate remaining balance from billing data, but no official endpoint.

I'm getting insufficient_quota but the usage dashboard shows $0 spent this month. Why? This usually means your free credits expired (Cause 4) or you're hitting a project-level limit that doesn't show up in the org-level usage view. Check the project settings specifically.

Should I use GPT-4o-mini instead of GPT-4o to avoid hitting the limit? GPT-4o-mini costs significantly less (~$0.15 per 1M input tokens vs $2.50 for GPT-4o). For development and testing, switching to mini can extend your budget 10–15x with minimal quality difference for simple tasks.


Related

Verified on 5 September 2026: SDK retry and exception behaviour reproduced against openai 3.8.0 with a local mock server (output shown above). Billing-console steps not re-verified on this date.