How to cap spending on a generation API key
The usual way to give an agent access to a generation model is to put a provider API key in its environment. That key has no ceiling. If the agent loops — and agents loop — the only thing standing between a bug and a large invoice is how fast you notice.
This is not a hypothetical failure mode. It is the default one.
Three things a spending cap actually needs
Prepaid, not postpaid. A balance that can reach zero is a hard stop. A credit card on file with a monthly invoice is not a cap; it is a report of what already happened.
Checked before the spend, not after. Genace deducts credits at submit time and rejects the request outright when the balance will not cover it:
402 insufficient_credits
NOT_ENOUGH_CREDITS
Not enough credits: balance is 12, this request needs 100
The job never starts. There is nothing to reconcile because nothing was spent.
Refunded when nothing was produced. A cap that charges you for failures is a cap that drifts. Failed and canceled jobs refund in full, so the balance only goes down when something came back.
Isolation is the other half
A ceiling on the account is necessary but not sufficient. If every agent, every project and every experiment shares one key, you get one number and no way to tell which of them is spending it.
Separate API keys give you separate attribution, and rate and concurrency ceilings apply per key:
| Tier | Requests per minute | Concurrent jobs |
|---|---|---|
| Free | 5 | 1 |
| Pro | 60 | 5 |
A free-tier key held by an experimental agent can produce at most one in-flight job at a time, no matter how enthusiastically it loops.
What this does not protect against
Being honest about the boundary: this caps spend, not waste. An agent can still burn its entire balance generating output nobody wanted, as long as each individual call succeeds. Prepaid credits bound the damage; they do not make the agent smarter.
It also does not help if you put the same key everywhere. The isolation only works if you actually issue separate keys.
Why a provider key cannot do this
Aggregators that ask you to bring your own provider key are handing that key straight through to whatever calls them. Whatever spending controls exist live at the provider, on the key you just delegated to an autonomous process.
Prepaid credits in front of the provider key is a different arrangement: the thing with the unlimited key is ours, and the thing your agent holds has a number attached to it that can reach zero.
Where these facts come from
- codebase: src/ai/api/credits.ts — balance check before submit
- codebase: src/ai/api/quota.ts — per-tier rpm and concurrency ceilings
- codebase: src/ai/jobs/service.ts — deduct on submit, refund on failure