Budgets
Five ceilings, each answering a different question. Together they make sure that a bug in an automation, a client that grew, or a comparison that runs long costs exactly what you decided and no more.
| Ceiling | What it bounds | Code |
|---|---|---|
| Workspace monthly budget | Everything the workspace spends in a calendar month, across every project and key. Set under Credits. | 402 `workspace_budget_exceeded` |
| Project monthly budget | One project — for an agency, one client. Set on the project. | 402 `client_budget_exceeded` |
| End-client budget by tag | One of your own customers, by the keys assigned to it and by every call whose client tag is theirs, in a calendar month. Set under Clients. | 402 `client_tag_budget_exceeded` |
| API key caps | Monthly, daily, and a ceiling on what a single call may spend. Set on the key. | 402 `key_budget_exceeded`, `key_daily_budget_exceeded` |
| Per-comparison budget | One comparison, in the panel or over the API. Required, never optional. | 409 `budget_exceeded` |
And the balance itself
Underneath all four sits the balance. When it reaches zero the answer is 402 `insufficient_credits`, whatever the budgets say. A budget is a promise you made about spending; the balance is the money that honours it.
Reading the codes
Every refusal is a 402 with the same JSON envelope and a different `error.code`, so a workflow can branch on one field. `insufficient_credits` needs a top-up; `workspace_budget_exceeded`, `client_budget_exceeded` and `client_tag_budget_exceeded` need a budget raised or the month to turn; `key_budget_exceeded` needs that key's cap raised; `key_daily_budget_exceeded` clears itself at midnight. None of them calls the provider, so a refused call costs nothing.
HTTP/1.1 402 Payment Required
{"error": {"code": "client_budget_exceeded",
"type": "insufficient_quota",
"message": "This project's monthly budget is spent. Raise it at …/panel/clients"}}The end-client ceiling, and its sixty seconds
The other ceilings are checked against the ledger as the call arrives. This one is checked at the gateway against a map of what each tagged client has left, and the map is refreshed once a minute — so a client can go up to sixty seconds past its cap before the first refusal, and what went through in that minute is billed as usual. The refusal names the client in `error.client`, so a workflow that serves several can tell which one stopped. Calls on the client's assigned keys are not in this map: they stop at the key's own caps, as they always did.
HTTP/1.1 402 Payment Required
{"error": {"code": "client_tag_budget_exceeded",
"type": "insufficient_quota",
"message": "The monthly budget for client \"acme\" is spent. Raise it at …/panel/clients",
"client": "acme"}}How a comparison stops at its budget
A comparison — of two catalogue models, or of an alias against a candidate — shows an estimate before running, computed from your examples and the models' prices. If the estimate is already above the budget it does not start: 409 `budget_exceeded`, with the estimate in the message, so you can raise the budget or trim the examples. If it starts and the real cost reaches the budget mid-run, the remaining cells are left unrun and the result says `stopped_at_budget`. You are billed for what ran.
HTTP/1.1 409 Conflict
{"error": {"code": "budget_exceeded",
"type": "invalid_request_error",
"message": "Estimated cost 0.42 € is above max_budget_cents=25."}}Alerts
The panel flags a low balance as soon as it is under the threshold of your last top-up, and shows how much of each budget the month has used. Auto-recharge, if you set it, is the alert that acts by itself — within its daily and monthly caps.
See also: Credits and balance · Limits · Error reference