Skip to main content
In this quickstart, we cap one customer, customer:acme, at $50 a month. Then we wrap an AI SDK call in a route handler, so the call runs only when the cap can cover it.
1

Create an API key

Create a runtime key in your project’s API key settings in the Unprice dashboard. Store it as UNPRICE_TOKEN in your server’s environment. Do not send it to a browser or commit it to a repository.
2

Install the package

The examples call OpenAI, so they also need OPENAI_API_KEY in your environment. If you already use @unprice/api, leave out @unprice/budgets and import from @unprice/api instead. It includes the same client.
3

Define the budget

Run this once, for example when the customer signs up or from a deploy script. Sending the same definition again changes nothing.
The call succeeds, and result.budget.balance.remaining is "50".A runtime key can create a budget and tighten it. Raising the cap later needs a config key. See who can change a cap.
4

Wrap the model call

spend reserves the most the call can cost, runs it, and settles what it actually cost.
The estimate must cover every billable unit, because actual may not exceed it. maxInputTokens returns a high bound, so most calls settle below the estimate. If your provider can count a prompt’s tokens before the call, use that count instead.
5

Handle the denial

When the cap cannot cover the estimate, spend throws BudgetExceededError and the model is never called. error.blocked names the limit, when it resets, and the remedy.
Send the route a prompt. It answers with { "text": ... } while the cap has room, and with a 402 once it does not.spend throws other errors when Unprice cannot be reached or the work fails. Read errors and recovery before you go to production.
6

Check the balance

remaining is now below "50" by what the call cost. balance.limits holds each limit’s consumed, held, and remaining amounts, and history holds the last ended periods.

Next steps

Keys and limits

Cap runs and agents, combine windows, and close a budget.

Serverless functions

Settle after the response with waitUntil.