Unprice Budgets

Hard caps. Per key. Actually hard.

Every paid call checks the budget first. A call that would go over the cap never reaches the provider. Your billing stays the same.

Get an API key
npm i @unprice/budgets
01Too late

Billing is too late.

An alert is not a cap. By the time it arrives, the money is spent.

The nightone agent run · traced
run:r_42 startedresearch agent
model callsnever stopped
usage alertover the $500 budget
spent when the alert arrived$1,204.00
check before each callnever ran
cap on run:r_42none
02Per key

Your gateway caps your provider bill. Budgets cap every key you pick.

One shared cap lets one runaway agent block every customer. A budget per key, such as customer:acme, stops only the runaway.

One capon the provider key
customer:acmerunaway agent
customer:globexrefused
customer:initechrefused
customer:umbrellarefused
cap reachedevery customer refused
A budget per keyhard caps · per customer
customer:acme$50.00 of $50 · 402
customer:globex$12.40 of $50 · running
customer:initech$3.10 of $20 · running
customer:umbrella$31.75 of $50 · running
the runaway agentstopped at its own cap
03Two calls

Set a cap. Wrap the call.

spend holds the estimate, runs your function, and counts only what it actually cost. If the cap can't cover the estimate, your function never runs.

agent.ts
1import { Unprice } from "@unprice/budgets"
2
3const unprice = new Unprice({ token: process.env.UNPRICE_TOKEN! })
4
5// 1. Set the cap once.
6await unprice.budgets.upsert({
7 key: "customer:acme",
8 unit: "USD",
9 limits: [{ amount: "50", window: "month" }],
10})
11
12// 2. Wrap the call your agent already makes.
13const text = await unprice.budget("customer:acme").spend({ estimate }, async () => {
14 const r = await generateText({ model, prompt, maxOutputTokens })
15 return { value: r.text, actual: costOf(r.usage) }
16})

Nothing in your billing stack changes.

plansuntouched
subscriptionsuntouched
invoicesuntouched
payment provideruntouched
04Checks

Zero-millisecond checks. Or one hop away.

Local mode spends from a lease, a slice of the budget held in memory, so a check makes no network call. Remote mode makes one round trip. Both enforce the same cap.

Local modelong-running processes
0network calls per check
answered froma lease in memory
use it inservers · workers · agent runners
reports usageonce a second
budget(key, { mode: "local", lease: { amount: "5" } })
Remote modethe default
1network round trip per check
answered bythe budget
use it inserverless · edge · jobs
if Unprice is downnew work is denied
budget(key)

The lease comes out of the budget first, so local mode can't overspend.

Run the latency benchmark
05The questions

Questions before your first cap.

Do I need Unprice billing?
No. Budgets work with the billing you already have. Read the overview
Doesn't my AI gateway already have a cap?
A gateway cap usually covers your whole provider key, so one runaway agent blocks every customer. A budget caps any key you choose, before the call runs.
Can parallel calls overshoot the cap?
No. In the test suite, 100 parallel $0.75 calls against a $50 cap admit 66 and refuse 34. Read the test
Can my agent raise its own cap?
No. Raising a cap needs a config key. Keep that key away from the agent.
What happens if Unprice is unreachable?
Remote checks deny new work. In local mode, the process keeps spending its lease until the lease expires.
Is it open source?
Yes. The SDK is MIT and the runtime is AGPL-3.0, and you can run it in your own Cloudflare account. On the hosted cloud, budget state may live outside the EU. Read the source
What does it cost?
Nothing during early access, and there is no card at signup.
06Start

Put a hard cap in front of your agent today.

Get an API key, install the package, and wrap one call.

npm i @unprice/budgets