Read the cost-intelligence dashboards
The Analytics API reference documents the aggregate cost endpoints — this guide is the prose walkthrough for the cost-intelligence surfaces that sit on top of them in the Orbit console, and explains what the unit economics actually answer. Use it when a margin question lands: what does a message, a voice minute, an AI token, or a video minute actually cost us per unit, and where is the margin in that? Example requests in this guide use the APIs directly; most operators read the dashboards in the console and use the APIs for export or integration.What a cost surface is
Every cost surface reads prices that were already recorded on your usage rows — the dashboards never re-price traffic. A message, call, or AI event is priced at the moment it is billed against your wallet, and the cost surfaces aggregate those recorded charges into spend, volume, and unit-cost views. Because the inputs are the same wallet charges in every case, the surfaces reconcile with each other: the “Total spend” headline on the Channel costs page is the same money the Billable usage records panel and the per-conversation P&L draw from. Access is role-scoped per surface. The money-family surfaces — Channel costs, LLM spend, Conversation P&L — restrict to the owner, admin, developer, and billing roles on the console, because they expose aggregate cost and margin analysis. The room-usage analytics API additionally admits the viewer role, as it reports volumes rather than money.Channel costs — Insights → Channel costs
Console route:/insights/costs, page title “Channel costs”. This is the unit-economics hub: one window (24 hours to 12 months, or a custom range) applied to every outbound channel at once.
What the page answers, top to bottom:
- Headline tiles — total spend, billed messages, and average cost per message across all channels in the window. The average is total spend ÷ billed messages, computed at sub-cent precision, so a channel mix dominated by low-cost SMS still reports a truthful blended unit cost.
- Spend over time — daily total spend for the window.
- Cost by channel — per-channel spend, message volume, and average cost per message, with a totals footer. The footer sums every channel — SMS, MMS, voice, WhatsApp, email, and the rest — so it always equals the Total spend headline. Spot the expensive unit here: if WhatsApp’s cost per message runs five times SMS’s, that is the row to act on.
- Billable usage records — carrier-parity counters (the data export sheets traditionally call usage records) for SMS, MMS, and voice, with an optional per-country split. Voice appears here in minutes; messaging in messages. This panel is deliberately carrier-scoped — it mirrors the bill a carrier would show — so it will not equal Total spend. The panel therefore shows a numeric reconciliation line for the non-carrier spend (email, chat, RCS, and similar) that is included in Total spend but not billed as carrier usage: the gap has an amount, not an apology.
The response carries three blocks under
data:
Sum
by_channel[].total_spend and you get totals.total_spend exactly — that equality is the dashboard-versus-API check step later in this guide makes use of.
Billable usage records — carrier-parity counters
The Billable usage records panel readsGET /api/v1/messages/usage/records — a carrier-parity aggregate over the billed rows, shaped after the usage-records surface a carrier’s export would give you:
The response holds
period_days (the resolved window) plus a records[] array. Each record is one bucket in the (sms | mms | voice) × (inbound | outbound) matrix:
Two conventions in
count explain every gap you will hit between this panel and the Billed messages headline:
- SMS is counted by segment, not by message. A 240-character SMS is two segments, so it appears twice in
sms-outbound.countbut once as a billed message. The headline tile counts priced outbound messages; the records panel counts billed segments — it is expected to be higher, and it is the number a carrier bill would show. - Inbound traffic is included (
sms-inbound,mms-inbound,voice-inbound), because inbound SMS/MMS bills on most carriers. The headline tile counts outbound charge rows only.
AI spend — Insights → LLM spend
Console route:/insights/llm-spend, page title “LLM spend”. AI cost shows up as token spend, not message spend: the dashboards report tokens and cost per agent, per model, per feature, and per conversation. Read it alongside Channel costs — the blended cost of an AI-handled conversation is its telephony leg (Channel costs, above) plus its token leg (here). All money on every LLM-spend route is integer cents; format it with your org wallet currency.
Four routes back the page, all under /api/v1/insights/llm-spend/:
GET .../overview — the dashboard header in one roundtrip:
GET .../summary — the breakdown table. Query parameters: from / to (ISO-8601 datetimes; default window is the last 30 days), groupBy (agent | model | conversation, default agent), and limit (top-N rows by cost, default 50). Each row in groups[] carries group_id, group_label, model, total_tokens, total_cost_cents, and conversation_count, and totals carries the window-wide tokens/cents/conversation count that back the share-of-cost column. Swap groupBy=model to answer “is the expensive agent actually expensive, or is it the model it runs on?” — the same spend, regrouped.
GET .../timeseries — one bucket per time slot for the trend line. granularity is hour (capped at a 14-day window) or day (30-day default window); each bucket carries total_tokens and total_cost_cents.
GET .../top-conversations — the runaway-conversation drill-down: the highest-cost conversations in the window (capped at 50), each with conversation_id, agent_id, agent_name, model, total_tokens, total_cost_cents, and started_at. Pair it with a budget: GET .../budget returns the org’s monthly/daily caps and per-channel thresholds, and PUT .../budget replaces them.
Per-conversation telephony P&L — API
The per-conversation economics endpoint,GET /api/v1/analytics/cost-per-conversation, groups priced message and call charges by conversation over a window you supply and returns the top conversations by telephony spend:
limit caps the returned rows. Use it to answer “what does a resolved WhatsApp conversation actually cost us in carriage?” without exporting to a spreadsheet.
Unit-cost formulas
Two formulas cover most margin questions. Run them on the same 30-day window so your denominators share an accounting period. Cost per conversation — three legs, one denominator:analytics/costs and the settled rollup average answer different questions with the same denominator convention: the channel row tells you what the unit costs fleet-wide right now; the rollup tells you what the campaign’s units actually cost once they settled.
Verify: dashboard totals against API sums
Whenever a number on a cost surface is about to drive a pricing or carrier decision, spend two minutes proving the surface against its own API:- Pick one window — say 30 days — and read the Total spend headline on
/insights/costs. - Pull
GET /api/v1/analytics/costs?days=30&group_by=dayand sum two ways:totals.total_spend, andΣ by_channel[].total_spend. All three numbers — headline, totals block, channel-footer sum — must match to the cent. - Cross-check the Billable usage records panel: pull
GET /api/v1/messages/usage/records?days=30and confirm each console row equals the API record for the samecategory. Expect the records’ SMScountto exceed the Billed messages tile — segments versus messages, plus inbound — and expect the panel’s non-carrier reconciliation line to cover the rest of Total spend. - On
/insights/llm-spend, the by-agent table’s column sum must equal the window-widetotals.total_cost_centsfromGET .../summary?groupBy=agentfor the same window, andoverview.month_to_date.spend_centsmust equalsummary?groupBy=agenttotals run from month start to now.
period_days, from/to, and per-row currency before suspecting the surface. Both dashboards are cached (60 s and short poll intervals), so a fresh send can also lag a screen refresh by under a minute; the API is the tiebreaker.
Wire the spend to an alert
Cost surfaces are read-heavy; the tripwire around them should be alert-heavy. The landed patterns:- Set per-API-key usage ceilings with threshold badges per Per-API-key usage budgets and threshold alerts — the earliest signal that an integration’s traffic shape (and therefore its spend) has left the plan.
- Grade spend velocity with the anomaly rules in Usage anomaly alert rules, and hard-cap the AI leg’s caps with the budget config behind
GET/PUT /insights/llm-spend/budget(monthly/daily caps, per-channel thresholds, soft-alert percentage) instead of discovering a runaway agent on the month-end P&L. - For a custom check, schedule the verification recipe above in your own automation and alert when
Σ by_channel[].total_spendfor a day crosses a threshold you provisioned — the same equality check it does for reconciliation doubles as a spend-rate monitor. AI agent cost controls covers the hard caps for the AI spend leg.
Video usage — room minutes
Video does not bill per message — it bills per participant-minute, so its economics live on a usage surface of their own:GET /api/v1/video/rooms-analytics/usage, optionally with from / to datetimes (30 days by default). The response gives an org summary — total sessions, total room-minutes (room wall-clock, so a 10-minute room with 4 participants is 10 room-minutes ≈ 40 participant-minutes of metering), average and maximum peak participants, recording success rate, and join failures — plus a daily series for the window. Multiply room-minutes by your participant mix to sanity-check video spend against the rate card. Soft-deleted sessions are excluded. When a video-spend question is really a quality dispute — a degraded session the tenant blames the platform for — the per-session QoE report in Monitor in-call video quality is the evidence surface to pair with the usage numbers.
Put the legs together
Margin per interaction is the assembly: the interaction’s price on your rate card, minus the channel leg (Channel costs per-channel unit costs, or the per-conversation P&L for individual conversations), minus the AI leg (LLM spend per conversation when an agent handled it), minus the video leg (room minutes when the interaction happened in a room). Run the assembly on a 30-day window and two things fall out: which channels carry the volume at the widest per-unit margin, and which conversations cost more to serve than their outcome is worth.See also
- Analytics API reference — endpoint shapes for the cost and usage payloads
- Insights API reference — LLM spend and margin analytics endpoints
- Read the Insights dashboards — the non-cost Insights surfaces
- Per-API-key usage budgets and threshold alerts — dashboard tripwires for runaway integration spend
- Usage anomaly alert rules — spend-velocity anomaly detection
- Monitor in-call video quality — the per-session QoE report behind video usage charges
- AI agent cost controls — budgets and hard caps for the AI spend leg