Burn rate and wallet runway
Orbit bills from a prepaid wallet. Every message, voice minute, and AI token debits the balance as it happens, and every debit lands in the transaction ledger behindGET /api/v1/billing/transactions. Because the wallet drains
with every send, the question a finance operator actually asks is not “what
did we spend this month?” but “at this pace, when does the wallet hit zero?”
Burn rate is that answer as a number you can poll.
GET /api/v1/billing/burn-rate returns your average daily spend over a
lookback window, the live wallet balance, and a projection of how many days
of balance remain at that pace. It is a read-only forecast: it reports the
pace, and it never throttles sending, never tops up the wallet, and never
sends a notification by itself. When you want the platform to act, pair it
with spend caps and
usage anomaly alerts, covered below.
1. Why burn rate is a first-class metric
A prepaid wallet makes runway an operational concern. A wallet holding 42.50 a day has about 35 days of sending left; when the balance reaches zero, sends start failing for insufficient balance, mid-campaign if nobody was watching. Spend reports tell you where the money went after the fact. Burn rate tells you how long the current balance lasts before the hard stop, while there is still time to top up or slow down. It is deliberately different from the two guards that can act on their own:- A spend cap is a hard threshold you set. When spend crosses it, Orbit pauses outbound sending. It is deterministic and enforced, but it fires only at the line you drew, not before.
- A usage anomaly alert notifies you when a metric crosses a threshold or deviates sharply from your learned baseline. It tells you something unusual is happening, not how long the wallet lasts.
- Burn rate is a forecast. It divides the balance by the recent daily pace every time you ask, so a traffic increase shows up as a shorter runway on the next poll, days before any cap or alert would trip.
2. The computation window
The endpoint aggregates wallet debits over a caller-selected lookback window:
Within that window:
- Only debits count as spend. Top-ups and grants are excluded, refunds are excluded, and operator adjustments applied to your balance are excluded, so a large top-up yesterday does not read as “spending that much per day”.
- The divisor adapts to young accounts. If your first spend inside the
window is more recent than the full window, the average divides by the
days actually elapsed (at least one) instead of the whole window. The
response’s
lookback_daystells you which divisor was used, andfirst_spend_atgives the first spend timestamp in the window. - The projection is balance divided by pace.
projected_days_remainingis the live balance divided by the average daily spend, truncated to one decimal place. It isnullwhen there is no recent spend, because there is no pace to divide by; dashboards render that as “no recent activity”. - Results are cached for about a minute. Polls inside that window return the same snapshot, so a dashboard that re-fetches on focus stays cheap and consistent. A poll also never observes a partially computed answer: concurrent polls share one computation.
- A data blip degrades to zeros, never to an error. If the billing data behind the endpoint is briefly unavailable, the endpoint still returns 200 with zeroed projections rather than a 5xx, and the degraded snapshot is not cached, so the next poll recomputes and self-heals. Treat an all-zero response right after a healthy one as “retry in a minute”, not as “spend stopped”.
3. How the balance enters the forecast
The two halves of the ratio come from different places, and both are the same numbers you see elsewhere in Orbit:current_balance_minoris the live wallet balance, the same valueGET /api/v1/billing/balanceand the dashboard balance widget report. If that live read is itself unavailable, the response reports a zero balance, and therefore zero days remaining, rather than an error.avg_daily_spend_minoris computed from the transaction ledger, the same ledgerGET /api/v1/billing/transactionspages through.
projected_days_remaining on
the next poll even while the spend side of the ratio is still within its
cache minute.
All *_minor fields are integer cents of the wallet currency (USD);
divide by 100 for dollars. Top-ups paid in another currency are converted
into the wallet on the way in (see
wallet currency conversion), so the
runway math is always single-currency.
4. Endpoint contract
days value
degrades to the 30-day default rather than rejecting the request.
Response fields, inside the standard { data, meta } envelope:
Each
by_channel row carries channel, month_to_date_minor,
last_7d_total_minor, and projected_month_end_minor (the same
month-to-date plus last-7-day-pace formula, per channel). Channel names are
sms, mms, whatsapp, voice, email, rcs, agents, verify,
numbers, marketplace, and other; the rows always sum back to the
headline projected_month_end_minor.
200
5. How it relates to spend caps and anomaly alerts
The three instruments answer different questions, and a mature billing setup uses all three: burn rate to see the runway, anomaly alerts to hear about a sudden change in pace, and spend caps as the hard stop that enforces the limit you are comfortable with.
The division of labor matters. A spend cap set at $2,000/month says
nothing about whether the wallet survives to month end; a burn-rate poll
on day 20 saying “6 days of balance left” says nothing about whether the
pace is anomalous. An anomaly alert on a spend surge catches the compromise
or misconfiguration that a steady, legitimate ramp will not trip, while the
burn-rate projection catches the legitimate ramp that no baseline will
ever flag. Because burn rate never acts, nothing on this page can pause
your traffic: the forecast is advisory until you, or a cap you configured,
decides otherwise.
6. Example: chart runway in Grafana
The endpoint is built to be polled. A common pattern is an hourly cron that publishesprojected_days_remaining as a Prometheus gauge via the node
exporter textfile collector, then a Grafana panel and alert rule on top:
projected_month_end_minor into a month-end forecast panel next to
your committed spend budget.
Remember the contract while wiring alerts: a zeroed response during a
billing-data blip is a 200, and null means “no recent spend”, not
“exhausted”. Alert on sustained values, and keep the real hard stop where
it belongs, in a spend cap.
Related
- Billing overview: the whole wallet surface, including the burn-rate summary section.
- Spend caps: the deterministic hard stop.
- Usage & anomaly alerts: threshold and learned-baseline notifications.
- Wallet currency conversion: how foreign-currency top-ups land in the wallet the forecast divides.