Authorize customer spend before paid work runs.
Sell credits and usage-based plans without eating over-budget customer work. Unprice is the open-source customer money path for usage-based SaaS.
- License
- AGPL-3.0 open source
- Access
- Free during early access
- Payments
- Your Stripe account
- Custody
- Funds stay with you
the paid action asks before it runs
Budget check
is this spend commercially allowed?
$4.10
remaining
allow · within budget
200
pro@v3 · $0.002/token
reserve → capture · balanced
deny · over budget
429
no cost created · nothing to explain
Every step in this path is a method in the public SDK. Run the check in shadow beside the logic you already run — TypeScript, REST, or curl.
By invoice time, the paid work already ran.
A customer triggers the expensive action. Your counter notices later; your invoice explains it weeks later. Blocked-too-late cost is margin you already spent — and when the customer disputes it, engineering turns into invoice support.
A Redis counter is not a budget: it cannot prove which plan version applied, which credits were reserved, or why a request was denied.
“Why were we charged $1,204? We set a $500 budget.”
Watch paid work stop before it creates cost.
Click a paid action against the plan. Each request is allowed, flagged, or denied before the work runs — and the same decision explains the invoice line later.
awaiting the first request
—
reason = no_request_sent
next = click a paid action on the plan
The first integration is two calls.
Define one plan version, then sign up one customer against it — customers.signUp runs once, at your own signup, and returns the customerId you store. After that, access.check guards the paid action on every request, next to the code you already trust. Nothing has to block production traffic on day one.
1import { Unprice } from "@unprice/api"23const unprice = new Unprice({4 token: process.env.UNPRICE_TOKEN,5 baseUrl: "https://api.unprice.dev",6})78// Once, at your own signup: subscribe the customer to a9// plan. Unprice provisions the subscription and its10// entitlements, then returns the id you store.11const { result: signup } = await unprice.customers.signUp({12 name: "Acme Inc.",13 email: "[email protected]",14 planSlug: "pro",15 externalId: "user_123", // your id for this customer16 successUrl: "https://your-app.com/welcome",17 cancelUrl: "https://your-app.com/pricing",18})1920// Every request after that: check before the paid21// action runs.22const { result, error } = await unprice.access.check({23 customerId: signup.customerId,24 featureSlug: "tokens",25})2627if (error) {28 console.error(error.message)29 return30}3132if (!result.allowed) {33 // Denied in the request path — no cost was ever created.34 throw new Error("Denied before paid usage ran")35}3637// Allowed: run the paid action. The same decision38// explains the invoice line later.
usage.consume, budgeted runs, invoice evidence — lives in the docs.Explore the request-path SDKTry it without touching your current logic.
Nothing blocks traffic until the evidence convinces you. When the shadow decision matches reality, switch access.check to usage.consume and enforcement is one line, not a migration.
- 01
Shadow
Run the decision beside the logic you already trust. Compare answers in without changing behavior.
runsaccess.checkmutatesnothing · read-onlyblocksnothing - 02
Sandbox
Prove the path before a dollar moves. Model customers, plan versions, budgets, credits, etc.
processornone · built-in Sandboxcustomerssimulatedevidencereal · inspectable - 03
Your own Stripe
Go live in your own account. Unprice owns the money path; your provider still captures the payment.
funds flowyours · alwayscaptureyour Stripe accountunpricenever in the middle
Why not just Stripe?
Keep Stripe for payment capture. Unprice owns the customer money path before and around the invoice: plan versions, entitlements, budgets, credits, ledger captures, and evidence.
Does Unprice touch the money?
No. Your app asks Unprice before paid work runs and gets an allow or deny with evidence attached. Your payment provider captures the payment — Stripe today, in your own account. Unprice owns the decision, the ledger, and the evidence; it never sits in your funds flow.
Why not an AI gateway?
Gateways cap provider spend. Unprice governs what your customer is allowed to spend and connects that decision to invoice evidence.
Is it safe enough for money logic?
Do not adopt it all at once. Read the source, run one request path in shadow, prove it on Sandbox, then enforce only when the evidence matches.
Do I need Cloudflare?
Today, yes. The runtime deploys to your own Cloudflare account — Workers, Durable Objects, Queues — because the spend decision needs fast per-customer state where requests run. Your account, your data, your keys.
The pricing is as explainable as yours will be.
The core is AGPL-3.0 and free to run in your own Cloudflare account. The hosted cloud is free during early access, with no card at signup. Payments settle to your own Stripe account either way — Unprice never sits in your funds flow.
The money path is yours to read, fork, and run — it cannot be acquired out from under you. The full argument is in the manifesto.
one plan version · one customer signup · one shadow check
one afternoon · free during early access · no card
Adopt in shadow: sign up one test customer, then run one read-only access.check beside the logic you already trust, blocking nothing. If the decisions never match your reality, delete that line and walk away — nothing in your stack changed, no card on file, no contract to exit. The only trace left is the one test customer inside Unprice. Enforce only when the evidence convinces you.
Not sure where to start?
Tell me the action that burns margin when a customer runs it — an LLM call, a workflow, an API job — and what stops it today, if anything. I'll reply personally with a concrete first step: where to put the check, what to run in shadow beside what you already have, and whether to block each request or cap the whole job.
— Seb, founder of Unprice