APIMODELSAPIMODELS

"Insufficient credits" / "credit reservation failed": what it means

TL;DR Short answer: this request needed more than your available balance, so it was not run and nothing was charged. The usual causes are other requests still running and holding credit, or a request whose maximum cost (images, seconds, resolution, max_tokens) is larger than you expect. Top up, or lower concurrency or the size of the request.

When you create an image, video or audio task, its full price is reserved from your balance before anything is generated. When the task finishes you are charged what it actually cost (for example only the images that were delivered) and the rest is released; if it fails, everything is released. A task can only start when your available balance, total minus what is currently reserved, covers its price.

The error tells you the numbers: "this request needs $0.1200 but only $0.0450 is available ($0.3000 is held by requests still running)". The first figure is this request's price, the second is what you can spend right now, and the part in brackets is credit held by your other requests that have not finished yet.

Chat and other language-model requests are checked just before the call, against an estimate of the input plus max_tokens of output with a 20% margin.

The three ways it shows up

WhereWhat you getStatus
Creating an image / video / audio task"Insufficient credits: this request needs $X but only $Y is available ($Z is held by requests still running). Please top up and try again; nothing was charged."HTTP 402; no task is created
A task that already has an id"Your account balance was too low to start this request, so it was not run or charged." (or the message above)state "failed", failCode "INSUFFICIENT_BALANCE"; this happens when several requests arrive at the same moment
Chat and other language-model calls{"error": {"message": "Insufficient credits for this request", "type": "insufficient_credits"}}HTTP 402

Why it happens when your balance looks big enough

Requests still running hold credit. Every request in progress keeps its full price reserved until it finishes. If you send a batch in parallel, the reservations add up, and once they exceed your balance the later requests are refused even though none of them has been charged yet. The "held by requests still running" figure in the error is exactly that amount, and it comes back as each running request finishes.

A request reserves its largest possible cost. Image requests reserve the number of images times the per-image price plus any reference-image fees; video requests reserve the requested seconds at the per-second price for that resolution, plus reference-video seconds where they are billed; language-model requests reserve for max_tokens of output, or for the model's default limit when you do not set max_tokens. A 4K, four-image or 15-second request can need far more than the one you sent a minute ago.

How to fix it

Top up on the Balance page of the console, by card, Alipay or USDT. If you run jobs unattended, turn on auto top-up there: save a card, pick a threshold and an amount ($10, $50, $100, $500 or $1,000), and the account is topped up whenever the balance falls below the threshold.

Cap concurrency for batches. Keep the number of requests in flight at or below your available balance divided by the price of one request, and check GET /v1/balance (the balance field is what you can spend now) before sending the next wave.

Set max_tokens on language-model requests. Without it the pre-check assumes the model's full output limit, which can be refused on a small balance even when the reply would have been short.

Make the request smaller: fewer images per call, a lower resolution or a shorter duration all lower the amount reserved.

Handling it in your code

Treat HTTP 402, failCode "INSUFFICIENT_BALANCE" and error type "insufficient_credits" as one condition: stop sending, alert whoever tops up the account, and resume after the balance is back. Retrying in a loop will not help, because nothing changes until credit is added or running requests finish.

Quick start

cURL

# Available balance before sending a batch (free, no credits charged)
curl https://api.apimodels.app/v1/balance \
  -H "Authorization: Bearer $APIMODELS_API_KEY"
# → { "code": 200, "msg": "success",
#     "data": { "balance": 12.5, "total": 12.8, "frozen": 0.3, "currency": "USD" } }
# balance = total − frozen; frozen includes credit reserved by requests still running

Python

import os, requests

H = {"Authorization": f"Bearer {os.environ['APIMODELS_API_KEY']}"}
price_per_request = 0.05        # what one of your requests costs
available = requests.get("https://api.apimodels.app/v1/balance", headers=H).json()["data"]["balance"]

max_in_flight = int(available // price_per_request)
if max_in_flight == 0:
    raise SystemExit("Top up first: one request costs more than the available balance")
print(f"Run at most {max_in_flight} requests at the same time")

FAQ

Was I charged for the request that failed with insufficient credits?

No. The request was refused before it ran, so nothing was charged and nothing stays reserved for it.

My balance shows enough credit. Why was the request refused?

Part of your balance is reserved by requests that are still running, and a request reserves its largest possible cost. Compare the "needs" and "available" figures in the error; the bracket shows how much your running requests are holding.

What does "frozen" mean in GET /v1/balance?

Credit that is reserved and cannot be spent right now, mostly by requests still running. It is settled when they finish: the actual cost is charged and the rest returns to your available balance.

Can the account top itself up?

Yes. On the Balance page of the console, save a card and turn on auto top-up with a threshold and an amount of $10, $50, $100, $500 or $1,000.

Why do chat requests ask for more credit than the reply costs?

The check runs before the reply exists, so it assumes the longest possible reply (max_tokens, or the model's default limit) plus a 20% margin. You are only charged for the tokens actually used. Setting a sensible max_tokens lowers the amount the check asks for.

Related

掲載メディア
APIMODELS on Product HuntAPIMODELS featured on ToolifyAPIMODELS featured on There's An AI For That