The loop
- Add credits.
POST /v1/organizations/billing/checkouttakesamount_centsand returns a hosted checkout URL. The amount is priced inline, so there is no product catalog to pick from — any amount between 500 and 1,000,000 cents (10,000) works. - Stripe reports the payment. A completed checkout credits the ledger. An asynchronous payment method credits when it settles instead.
- A refund claws the credits back.
- Usage debits the ledger as work finishes.
curl for this one. The console’s Billing page sends the request
on your behalf, carrying your browser session:
plan instead of amount_cents and you get a 400: the field survives
only so an older client gets an explicit refusal rather than silently buying
credits when it meant to start a subscription. There are no subscriptions.
POST /v1/organizations/billing/portal opens Stripe’s own portal for payment
methods and receipts. It answers 409 until you have made a purchase — the
Stripe customer is minted at first checkout, so before that there is nothing to
manage.
Reading your own numbers
Five endpoints sit behind the console’s Billing page, and all five take an API key.Reconciling a bill
usage/breakdown carries three money columns, and reading the wrong one is the
usual cause of a bill that “does not add up”:
For an ordinary account
charged_cents and spend_cents are the same number.
They diverge on an account that is not billed, where the balance never moves and
spend_cents is the only meaningful figure.
by_api_key splits the same period by key, and unattributed catches work with
no key behind it — the console’s own usage, and history from before key
attribution existed — so the key rows plus unattributed always sum to the
total. That is how you find which deployment is spending.
usage/breakdown accepts days from 1 to 365; usage/daily-breakdown
accepts 1 to 30 and answers 400 unless the organization has an explicit
per-second price configured. Use usage/breakdown for the general case.GET /v1/organizations/billing/credits returns them
paginated, newest first, with a signed credits_delta — positive for a
purchase, negative for a debit — and balance_after on each.
Things that surprise people
The balance is shown in minutes, not credits
The balance is shown in minutes, not credits
“You have 41 credits left” answers nothing. “About seven hours of audio
left” is the same fact in the unit the work is measured in, so
minutes_remaining travels on the wire beside the credit figure and
price_per_minute_usd says what a credit is currently worth. What a credit
buys moves with the rate card; the credit itself is always a cent.There is no automatic top-up
There is no automatic top-up
Pay-as-you-go stops dead at zero and nothing recharges a saved card. What
replaces it is a warning: when the balance falls below an hour of audio,
low_balance goes true, the console shows a banner, and an email goes out
— keyed per organization per hour, so a burst of work collapses to one.
The flag clears only when the balance climbs back, so a top-up re-arms the
warning and a long slide below it stays quiet. Watch low_balance
yourself if you want to act before a 429.A live session is charged once a minute, not at the end
A live session is charged once a minute, not at the end
A voice session debits on a one-minute beat while it is up, and the
balance and free-tier day are re-checked on the same beat. So a long call
cannot outrun the credit that started it, and a crash no longer loses the
whole call’s minutes. Reaching a limit ends that session, with the reason
named on the socket before it closes. See
Pricing and limits.
A short request rounds to zero, and is still recorded
A short request rounds to zero, and is still recorded
Debits round to the nearest cent, and at $0.001 a minute a cent is ten
minutes of audio — so an ordinary generation moves the balance by nothing.
It still writes a usage row carrying the exact cost in micro-cents, which
is what the consumption figures sum. A ledger that showed only
balance-moving events would look empty to an account that had been working
all day.
Test mode says so
Test mode says so
A deployment running against Stripe’s test mode returns
sandbox: true on
the credits response, and hosted checkout shows its own test-mode banner.
Credits land in that environment’s ledger for real; the money is not.Deployments with billing switched off
Billing is a capability, not a given. It is on only when the deployment has both Stripe credentials configured. With either missing:- Every billing route answers
404 Billing is not enabled on this deployment. - The credit gate always allows, so nothing is ever refused for quota.
- Free-tier daily ceilings do not apply — with no plans and no purchases there is no free tier to bound, only the operator’s own hardware.
Next
Pricing and limits
The rate card, the grant, and every ceiling.
Sessions
The conversations behind the minutes on your bill.
Errors
What an exhausted balance looks like on each surface.
Authentication
Why the payment routes refuse an API key.