Billing
Prepaid credits, BRL only, R$50 minimum. Sandbox is free. Production hard-blocks when the balance goes below -R$5 so an in-flight conversation can finish before you're cut off.
How it works
- Every organization has exactly one
credit_balance, denominated in BRL. - Top ups are one-off Stripe Payment Intents. We complete the top up in-transaction when Stripe's webhook arrives.
- Each billable event (
message.delivered, first-timephone_number.verified,tts.characters,llm.tokens.used) writes aUsageRecordpriced against the active rate card. - Sandbox usage records are written with
cost_brl = 0.
Top up
Top-ups are created from the dashboard, where the signed-in user can use Stripe Elements or PIX without exposing dashboard session endpoints as public integration APIs. The balance is credited atomically when Stripe's webhook marks the intent as succeeded.
5000 centavos). Lower amounts get a 400 validation_error.Balance and ledger
The ledger is a cursor-paginated stream of credits (top ups) and debits (usage records). Each entry carries the trace_id that produced it so you can reconcile a charge back to the exact message. Debit entries include uncollected_brl when delivered usage could not be fully collected without crossing the -R$5 production credit floor.
Rate card
Rate cards are effective-dated. The active card is the one whose window covers now. Current seed (BRL) looks like:
msg.outbound.marketing R$0.25 / conversation
msg.outbound.utility R$0.10 / conversation
msg.outbound.authentication R$0.08 / conversation
msg.outbound.service R$0.05 / conversation
phone.number.month R$50.00 / number / month
tts.characters R$0.0001 / character rendered
llm.tokens.used R$0.015 / 1k tokens (input + output)
template.generation R$0.05 / generation (production only)Spend limit
Set a monthly BRL cap per project from the dashboard. Once month-to-date production spend reaches the cap, POST /v1/messages returns 402 spend_limit_exceeded until the next calendar month rolls over — or you raise the cap. A spend_limit.hit webhook fires on the crossing.
Low-balance alerts
When the balance crosses the configured threshold downward (default R$10), a credit.low_balance webhook fires exactly once per decrement that caused the crossing. Subscribe to it to auto-top-up.
Invoices
Monthly CSV roll-up per project. BuildInvoiceUseCase is idempotent on (project_id, period_start); the download URL is a 15-minute presigned S3 GET.