The insufficient_quota error in the OpenAI API: causes and fixes

insufficient_quota arrives with a 429 status, but it's not a rate limit — it's money or a spend cap. Causes, exact codes, and handling in Python.

5 min · · errors · payments

The insufficient_quota OpenAI error arrives with status 429, and many people's first move is to retry, as with an ordinary rate limit. That won't help: the error is about money or a spend cap, not speed. Below: what insufficient_quota means, how to find the exact cause from the error code, how to handle it in Python, and what the same situation looks like in the Zukko gateway.

What insufficient_quota means in OpenAI

According to OpenAI's docs, errors related to billing and spend limits come with HTTP status 429. The general error type, error.type, can be insufficient_quota, and OpenAI advises checking the error.code field for the specific cause. The classic message text is "You exceeded your current quota, please check your plan and billing details".

The response looks roughly like this:

bash
{
  "error": {
    "message": "You exceeded your current quota, please check your plan and billing details. ...",
    "type": "insufficient_quota",
    "code": "credit_balance_exhausted"
  }
}

The key point from the docs: retrying such requests won't restore access. You need to top up or change the limit first.

Why the error happens: codes from OpenAI's docs

error.codeCauseHow to fix
credit_balance_exhaustedThe organization's prepaid credits ran outAdd credits in billing settings
organization_spend_limit_exceededThe organization hit the monthly spend limit you setRaise or remove the limit, or wait for the monthly reset
project_spend_limit_exceededThe project hit its own monthly limit; other projects keep workingRaise the limit in project settings or wait for the reset
organization_usage_limit_exceededThe organization reached its OpenAI-assigned usage limitRequest a higher limit or contact support

A few more common everyday causes:

  • A ChatGPT subscription doesn't include API credits. ChatGPT and the API are billed separately, so a paid ChatGPT Plus won't save you from insufficient_quota.
  • The key is from the wrong project. The key belongs to a project or organization with no money, while you topped up a different one.
  • A forgotten project limit. There's money in the account, but the project hit its own cap.

Telling these apart from a regular rate limit is easy: a rate limit clears after a pause (OpenAI advises waiting at least as long as the Retry-After header says). Billing errors have the codes from the table above, and a pause changes nothing.

How to fix insufficient_quota, step by step

  1. Look at error.code, not just the status. It tells you right away whether credits ran out or a limit kicked in.
  2. Check which key your code uses. An environment variable may be left over from an old project.
  3. Check the balance and limits of the organization and project in OpenAI's billing settings.
  4. Stop the retries. In the OpenAI Python SDK, a 429 becomes openai.RateLimitError, and the SDK retries it twice by default. For billing errors those are wasted requests: catch them separately and stop the job with a clear message.

The Zukko equivalent: 402 and key limits

In the Zukko gateway there's one balance for all models, in dollars. The situations from the table look like this:

OpenAIZukkoWhat to do
429 credit_balance_exhausted402, code insufficient_balanceTop up from $1
429 project_spend_limit_exceeded429 key_daily_limit_reached or key_monthly_limit_reachedRaise the key's limit in the dashboard or wait for the reset
429 rate limit429 without those codes — a limit at the model's providerRetry with a pause

Two differences from OpenAI worth reflecting in your code:

  • Insufficient balance is a 402, not a 429. The gateway checks the balance before sending the request to the model. In the OpenAI Python SDK, a 402 arrives as a generic openai.APIStatusError, and the SDK doesn't retry it — no wasted requests.
  • Limits are set per key, not per project. Each key has a daily and monthly dollar limit and a list of allowed models. A separate key per project gives you the same isolation as OpenAI's project spend limit. Details in the key limits docs.

From Russia you can top up via SBP or a Russian card (in rubles at the market rate at the time of payment), or with cryptocurrency. Step by step in the article on paying via SBP. You can check the remaining balance in advance via the API — see the balance reference.

How far $5 goes

Prices as of October 7, 2026. Take a request with 2,000 input and 500 output tokens; formula: (2000 × input + 500 × output) / 1,000,000.

ModelInput / output, $ per 1MOne requestRequests per $5
deepseek-v4.1-flash0.013 / 0.038$0.000045about 111,111
gpt-6.1-sol0.27 / 1.32$0.0012about 4,166
claude-sonnet-50.4 / 2$0.0018about 2,777

Checking the second row: (2,000 × 0.27 + 500 × 1.32) / 1,000,000 = (540 + 660) / 1,000,000 = $0.0012; 5 / 0.0012 ≈ 4,166. This is an example calculation: prices change; for the current list and prices, call GET https://api.zukko.pro/v1/models or open the Models page in the dashboard.

Handling billing errors in Python

The code below works both with OpenAI directly and through Zukko: it catches billing errors by status, type, and code, and leaves transient errors to the SDK's built-in retries. Note that the OpenAI SDK retries a 429 twice on its own before handing the exception to your code; it doesn't retry a 402 from Zukko.

bash
import openai
from openai import OpenAI

client = OpenAI(base_url="https://api.zukko.pro/v1", api_key="fetch_your_key")

BILLING_CODES = {
    # OpenAI
    "insufficient_quota",
    "credit_balance_exhausted",
    "organization_spend_limit_exceeded",
    "project_spend_limit_exceeded",
    "organization_usage_limit_exceeded",
    # Zukko
    "insufficient_balance",

If you're moving a project from OpenAI, only the base_url, the key, and the model names change; the rest of the code stays the same. Details in the article on migrating from the OpenAI API; replacing the key step by step is covered in an OpenAI API key in Russia.

To try it, create a key in the dashboard, top up any convenient amount, and set a daily limit on the key.

FAQ

I topped up my OpenAI balance, but insufficient_quota is still there. Why?

Look at error.code. If it says project_spend_limit_exceeded or organization_spend_limit_exceeded, the problem is the spend limit, not credits. Also check that the key belongs to the project and organization you topped up.

Does a ChatGPT Plus subscription give access to the API?

No. ChatGPT and the API are billed separately; the API needs its own credits.

What does Zukko return when the balance runs out?

Status 402 with code insufficient_balance. The request doesn't reach the model, so retrying before you top up is pointless.

Why is it a 429 at OpenAI but a 402 at Zukko?

That's each service's own design. OpenAI groups billing errors with rate limits under 429 and tells them apart by code; Zukko puts insufficient balance under its own 402 status, while 429 means a key limit or a provider limit.

zukko

Pay 25×
less

for Claude Code & ChatGPT

One fetch_* key and base URL api.zukko.pro — for Cursor, Claude Code, Codex, and any SDK.

Get API keyDocumentation

api.zukko.pro · fetch_*

insufficient_quota OpenAI: what it means and how to fix it · Zukko