Never lose money on a heavy AI customer
noburn checks every request against that customer's budget before it's sent.
Free plan · no card · OpenAI, Anthropic, Gemini- project
- usr_2841
- usr_7720
- run_c7
- usr_5106
- run_d2
Demo: 6 breakers armed. check() runs before every call.
Same $49 plan. Very different customers.
You find out when the invoice arrives, with no line for which customer caused it.
How noburn works
- Set a budget$15/moper customer, plan or agent run
- Check first$0.03 > $0.02 leftbefore the request is sent
- Stopped$0.00 billedyour provider is never called
With the Vercel AI SDK or LangChain, it's one line. Prompts never reach noburn.
What your heavy customers cost you
› noburn Pro is $49/mo · saves about $947 · 19.3× what it costs
How this is worked out
- - Heavy customers: customers × heavy share, rounded. Each costs your priced-in AI cost × how much more they use.
- - Without a cap you pay all of it. With noburn each customer stops at the budget you set, so the orange part is never sent and never billed.
- - A stuck night: Claude Sonnet ($3 in / $15 out per million tokens), a 30k-token conversation, 300 tokens out, one call every 10 s for 8 hours: 2,880 calls, about $272.
- - With noburn the agent is told at its first repeat and stopped at the 3rd identical call: about $0.28.
- - These are your inputs and our assumptions, not results from a noburn customer.
Fake accounts can't drain your free tier
One budget for a whole plan. One founder woke up to a $4,000 bill without it. How it works
Catches stuck agents, and tells them first
- call 1
search_orders("A-1042")ran - call 2
same call, same answertold: try something else - call 3
same call againstopped · $0.00
- changed course when told
- 19 of 20
- on stuck tasks, gpt-5-mini
- ½ the cost
- healthy tasks stopped
- 0
Our own test, October 2026. Small samples: 20 to 25 runs per model and mode. How we tested it
See what each client costs you
Breakers
38 more user caps- brightpath_dentalend-user cap$15.00 of $15.00tripped41 blocked
- harbor_realtyend-user cap$14.10 of $15.00armed0 blocked
- lumen_clinicend-user cap$11.20 of $15.00armed0 blocked
- acme_roofingend-user cap$6.40 of $15.00armed0 blocked
Your data, and what happens if noburn goes down
- noburn unreachableyour app keeps running, or fails closed. You choose.
- Traffic stays directnothing to reroute
- Stored in SingaporeAWS ap-southeast-1
Be one of our first five design partners
3 months free, then Pro at $49/mo. We set it up with you, and you get a direct line to the founder. If it saves you money, we publish the numbers together, and you approve every word.
noburn is a pre-flight spending cap for LLM API calls: one check in your code before each request, which blocks it if it would exceed the project, per-user or per-run budget. It is not a proxy.
How the pre-flight check works
// 1. ask before the callconst d = await guard.check({ model: 'gpt-4o', estimatedTokensIn: 1000, estimatedTokensOut: 300, endUserId, runId });
// 2. tripped? the provider is never calledif (d.blocked) throw new Error(d.blockReason);
// 3. record the real cost, off the hot pathguard.record({ model: 'gpt-4o', tokensIn: 980, tokensOut: 290, costUsd: 0.005, wasBlocked: false, endUserId, runId });check() → allow or block → your provider call → record()
noburn vs LLM gateways and observability tools
- Observability: Tells you what a call cost, after the provider has billed it.
- Gateways: Can genuinely cap spend, if every call is routed through their proxy.
- noburn: Decides before the call is sent, from inside your own code path.
Checked against vendor documentation in August 2026. Sources and the full comparison
Technical detail
Per-user and per-run spending caps
One check resolves every limit on the call. The first one it would cross stops it, and the response names which.
| cap | bounds | reason returned |
|---|---|---|
| Project | Total monthly spend across everything running under one project. | budget_exceeded |
| Per end user | A monthly dollar cap on one customer, so a single account cannot drain the project. | user_budget_exceeded |
| Usage quota | Dollars or requests per end user per day, week or month, set per plan or per user. | quota_exceeded |
| Plan budget | Every end user on a plan together, per day, week or month, so thousands of free accounts can't add up to a big bill. | plan_budget_exceeded |
| Per run | A single agent invocation. The cap that catches a loop before it compounds. | run_budget_exceeded |
| Loop | With the AI SDK or LangChain integration: the same tool call returning the same result a 3rd time, refused before it runs. | loop_detected |
| Stopped run | A run you stopped from the dashboard or the API. Every later call for it is refused. | run_stopped |
| Policy rule | A rule you wrote, on the model, budget utilisation or a context key you pass, that returns block. | policy_rule |
Try it: a retry storm against a run cap
Try it: a retry storm against a run cap
Simulation · nothing is sent
The storm: 20 requests time out after the model has answered, and each is tried 4 times. Every try is billed in full, unless check() refuses it first.
- never billed
- $0.00
- attempts refused
- 0 of 80
- billed before the trip
- 0 calls
What a cap does to a retry storm
All features
- Per-run caps: a retry loop stops at its budget, not at morning
- Per-user caps: one heavy user can't spend everyone's budget
- Usage quotas: a daily, weekly or monthly allowance per plan, with what is left returned on every check
- Remote stop: end a running agent from the dashboard or the API
- Never sees prompts: only the model, token counts and IDs you pass, checked and stored in Singapore
- Context is for rules, not content: short labels like plan: "pro" or feature: "chat" that your rules match on; used during the check and never stored, so keep customer data out of it
- Fail open or closed: onError 'allow' or 'block', your call
- Webhooks: budget.exhausted and call.blocked go to your endpoint
- Passthrough billing (Pro): add each customer's AI usage, plus your markup, to their next invoice in your own Stripe
Works with OpenAI, Anthropic and Gemini
Any provider, because check() is a call you make before yours, not a client you swap in: OpenAI, Anthropic, Google Gemini or a self-hosted model, from Node.js (@noburn/sdk) or Python (noburn). Known models are priced on the server from published rates; anything else takes the cost you send.
Adapters for the Vercel AI SDK and LangChain (Node.js), and LangChain and CrewAI (Python), ship in the published packages, with loop detection on by default.
What it adds to your request path
| property | value |
|---|---|
| calls added before yours | 1 (POST /api/v1/check) |
| calls added after yours | 0: record() is fire and forget |
| check runtime | Node.js, next to the database (Singapore) |
| repeat checks | answered in the SDK from a 10 s lease |
| provider socket when blocked | never opened |
| noburn unreachable | onError decides: allow (default) or block |
No production p50 is quoted here: there is not yet enough traffic to quote one honestly.
Pricing
| plan | price | recorded calls | projects | seats | passthrough billing |
|---|---|---|---|---|---|
| free | $0 | 10,000 | 1 | 2 | no |
| starter | $19/mo | 250,000 | 3 | 3 | no |
| pro | $49/mo | 5,000,000 | unlimited | 10 | yes |
Blocked calls are never counted. Enterprise: book a call.
Plan limits
Every plan enforces the same caps; what changes is how much traffic runs through them. Usage is counted per organisation and pooled across projects. Free and Starter stop hard at the limit. Pro continues at $0.001 per 1,000.
FAQ
What is noburn?
A hosted API and open-source SDK (Node.js and Python) that checks each LLM API call against a project, per-user and per-run budget before the call is sent, and blocks it if it would cross one.
How is it different from LiteLLM or Portkey?
LiteLLM and Portkey can also refuse an over-budget call, but only when all of your traffic routes through their proxy; noburn decides with one API call from your own code and never sits between you and the provider.
Does noburn see my prompts?
No: check() sends the model name, estimated token counts, and whatever end-user ID, run ID and context strings you choose to pass, while prompts and completions go straight from your code to the provider.
10 more questions
Which models does it price?
OpenAI, Anthropic Claude, Google Gemini, DeepSeek, Mistral and Llama models are priced on the server from published rates, and any other model is priced from the cost you send. Table version 2026-11-07.1: OpenAI GPT-4o, GPT-4.1, GPT-4, GPT-3.5 and the o-series; Anthropic Claude Haiku, Sonnet and Opus; Google Gemini 1.0 to 2.5; DeepSeek; Mistral Large and Small; Llama 3 and 4. Per-project overrides cover rates you negotiated yourself. When you send token counts for a model outside the table, it is never priced below $30 / $75 per million input / output tokens, so an unknown model cannot slip under a cap at $0.
What happens if noburn is down?
Your onError setting decides: 'allow' (the default) lets the call through so an outage on our side never takes down your product, and 'block' fails closed. The choice applies when the check fails or times out (2 seconds by default). 'block' returns noburn_unreachable, for the paths where spending nothing matters more than answering. 'allow' still applies cached policy rules and any local budgetCapUsd you set on the guard.
Will noburn ever stop a request it shouldn't?
Only when a budget you set is reached, or an agent repeats the exact same step and gets the same answer. Normal repeated work, like waiting for a job to finish or retrying a flaky service, isn't counted. In our tests no healthy task was stopped.
Do my developers have to change how they call OpenAI?
No. They keep their provider SDK and add a check before each call. With the Vercel AI SDK or LangChain, it's one line.
What happens to a customer who hits their limit?
The request is refused before it's sent, and your app gets a clear reason you can show them, like "monthly AI allowance reached". You decide what they see: an upgrade prompt, a wait, or a top-up.
How much latency does this add?
One HTTP request before your provider call, and nothing after it: record() returns immediately and reports in the background. A blocked call is faster than an allowed one, because the provider is never dialled. No production p50 is quoted, because there is not yet enough traffic to quote one honestly; time check() in your own staging project to see what it adds there.
Do blocked calls count against my plan?
No. The quota counts calls you actually recorded, so a call the guard refused costs you nothing in tokens and nothing in plan usage.
Can I cap one customer without capping the rest?
Yes. Caps resolve at three levels on the same request: the whole project, one end user, and one agent run. The tightest one wins and the response names which.
Can I stop an agent run that is already going?
Yes. Stop it from the dashboard or with POST /api/v1/runs/{id}/stop, and every later check() for that run returns run_stopped, whatever budget it has left.
Is the SDK open source?
Yes. @noburn/sdk on npm and noburn on PyPI are both MIT licensed, with no runtime dependencies.
Find out which customers are costing you money
npm i @noburn/sdk