Where you stand
GET /api/billing/summary returns one object with these sections.
Each section loads on its own. When one cannot be loaded it comes back
null
and its name appears in unavailable. So a null section named in
unavailable means “unknown right now”, and any other null means “none”.
attention lists what needs a person, most urgent first. Each item has a
code, a severity (ACTION_REQUIRED, WARNING or INFO) and a message
you can show as it is.
An agency exempt from payment is never told its wallet is low.
The transaction history
GET /api/billing/transactions is one paged list of everything that moved
your agency wallet in a window, newest first.
walletEffect is what the row did to your wallet. cashFlow is whether money
changed hands. For SUB_ACCOUNT_TOP_UP, amountUSD is what the sub-account
paid you.
CALL_USAGE counts only calls your wallet paid for: calls from sub-accounts
that do not rebill, calls you covered when a rebilled sub-account had no card,
and the part of a call that ran past a sub-account’s minutes. A call a
sub-account paid for from its own minutes is not a second charge to you, so it
is not on this list. It is in the usage figures below.
Filter with type and locationId. Filtering by sub-account leaves out
agency-level rows such as your own purchases.
Usage and cost
GET /api/billing/usage totals a window and breaks it down by sub_account
(the default) or by day.
callCostUSD and billedToClientsUSD describe the calls, so they lag the
money: a sub-account that bought minutes it has not used yet has paid you for
them already. Phone numbers and co-author usage belong to your agency, so they
appear in totals and in each day, never under a sub-account.
Sub-account wallets
GET /api/billing/sub-accounts lists every connected sub-account. A
disconnected one is not listed.
rebilling: whether the sub-account pays for its own calls from its own wallet, and theclientRatePerMinuteyou charge it.wallet:balanceMinutes(bonus minutes included, expired batches not),balanceUSD,debtMinutes, and whether the sub-account can see its wallet (visibility,ENABLEDorDISABLED).autoRecharge: set in dollars.thresholdUSDis the dollar balance it tops up below, andrechargeAmountUSDis what each top-up charges.creditGuard: whether the sub-account stops its own calls when its wallet is empty.pendingCredits: payments the sub-account has made that are waiting for credit in your wallet.
status is ACTIVE, LOW_BALANCE, IN_DEBT or DEPLETED. A
sub-account that does not rebill is funded by your wallet, so an empty balance
there is normal. The summary only flags rebilled ones.
GET /api/billing/sub-accounts/{locationId} adds the creditBatches behind
the balance, oldest first, which is the order they are drawn down.
Invoices and receipts
GET /api/billing/documents lists proof of payment.
scope=platform(the default): what your agency paid the platform. AnINVOICEfor your subscription, aRECEIPTfor each wallet top-up.scope=sub_accounts: what your sub-accounts paid you. Always aRECEIPT.
type (ALL, INVOICE or RECEIPT). The platform list is built
from two sources and capped. When truncated is true, it is not complete
history.
Changing billing
The same module changes billing. Two scopes split it by what a call does to money:billing:writechanges settings. Nothing is charged when the call returns, though switching auto-recharge on permits charges later.billing:chargecharges a card when the call returns.billing:writedoes not include it, every such operation needs anIdempotency-Key, and none of them is available to an assistant over MCP.
For a sub-account, every change needs your plan to include rebilling and Stripe
Connect to be connected, even a change that turns something off:
The walkthrough is Set up rebilling for a sub-account.
Windows
dateFromUTC and dateToUTC select whole UTC days. A timestamp selects the
day it falls on. Leave both out and the history and usage endpoints read the
last 30 days. A window can cover at most 366 days. Documents are not windowed
unless you ask. See Conventions.
Boundaries
- Adding cards, creating Stripe customers and connecting Stripe stay in the dashboard. The API never takes card details.
- Anything that charges a card needs the
billing:chargescope and anIdempotency-Key, and is not available over MCP. - Only an agency admin’s credential can change billing. Reads also admit a
staff credential carrying an agency of its own. A sub-account user gets
403either way, because every figure here is agency-wide. - A key needs the
billing:readscope to read.billing:writecovers it.billing:chargecovers neither. - A sub-account belongs to the agency that owns it. One that is only shared with you is not in your billing.
- A
locationIdthat is not one of your connected sub-accounts returns404, whether it does not exist or belongs to someone else.
In the API
- Get billing summary
- List billing transactions
- Get billing usage
- List billing documents
- List sub-account wallets
- Get sub-account wallet
- Update sub-account rebilling
- Charge a sub-account
- Every field, one line each: Glossary
Related
- Agencies, projects and sub-accounts
- Authentication for the
billing:readscope. - Metrics and how they are calculated for call outcomes rather than cost.
