What a call costs
A live call is billed on audio tokens, which cost about four times the same model's text rate on input and roughly 2.7 times on output. Metering is therefore split by modality rather than totalled: usage_summary reads the audio and text counts the SDK actually reports. A call that reports no tokens is charged from its own duration at the per-minute rate, never at zero.
Why modality is the unit#
On a text channel, a token is a token and a total is enough. On a voice call it is not: the same model charges very differently for audio than for text, and a call carries both — the caller's speech and the model's reply as audio, the brief and the mid-call notes as text.
| Stream | Relative cost | What produces it |
|---|---|---|
| Audio in | About four times the model's text input rate | Everything the caller says |
| Audio out | Roughly 2.7 times the model's text output rate | Everything the voice says |
| Text in | The model's text input rate | The brief, knowledge, memory, notes, supervisor guidance |
| Text out | The model's text output rate | Reasoning and tool arguments |
Multiply a total by any single rate and the answer is wrong by a factor that depends on how talkative the caller was. brief.usage_summary therefore reads the breakdown the SDK reports — input_audio_tokens, input_text_tokens, output_reasoning_tokens, session_duration — and prices each stream at its own rate.
The field that did not exist#
There is no input_audio_duration in that breakdown. An earlier version of the metering looked for one, found nothing, and recorded 0.0 seconds of audio for every call it ever metered — a number that is wrong in a way nothing complains about, because zero is a perfectly valid duration and every dashboard drew it happily.
Every session a call held#
A call is not always one model session. A session that refuses to start is opened again on the same model and once on the fallback; a session the server ends with a go_away is resumed carrying the conversation. Each of those is a separate usage report.
merge_usage adds them all. Before it did, a restarted call billed only the surviving session — so precisely the calls that had gone wrong, and therefore cost the most, were the calls that were under-charged. The record shows model_session_restarted when this happened, which is also the fastest way to see whether a line is quietly restarting sessions.
The context you pay for again every turn#
A Live session is re-billed for its entire context on every turn. That single sentence explains most of a voice bill: measured across production calls, 92% of input tokens are carried context rather than anything new the caller just said.
It also explains why the prompt budgets are as tight as they are. A thousand extra characters in a behaviour block is not a thousand characters once — it is a thousand characters on every turn of every call for as long as that profile is in use, and it slows first tokens as well.
Context compression is *sized* rather than switched on by default: COMPRESSION_TRIGGER_TOKENS and _TARGET_TOKENS decide when a sliding-window compression happens and what it compresses to. The default trigger is the model's whole context window, which means a call that never gets near it is never compressed — set the numbers deliberately if you run long calls.
A call that reports nothing#
Some calls end with no usage report at all — a session that died, a provider that answered nothing useful, a browser call with no worker behind it. Those calls are charged from their own duration at the published per-minute rate.
Charging them at zero would be the easy behaviour and the wrong one: the calls that fail to report are disproportionately the calls that went wrong, and a cost model that quietly forgives them tells a business its worst calls are free. The stale-call sweep works the same way — it charges what it closes.
Where to read the numbers#
GET /api/usage/voice is the per-call profiler. Like the rest of the ledger it is available to the platform operator rather than to a customer workspace, and it reports what was measured and states what was not measured instead of filling the gap with an estimate. A blank beside a figure means nobody knows, which is more useful than a confident number that came from arithmetic rather than from the wire.
On the call record itself, cost is stored in minor units alongside the provider's status, the ring and answer times and the quality snapshot, so a call's price sits next to the evidence for how it went.
Questions#
Why is a short call sometimes more expensive than a longer one?
Because context, not duration, drives most of the input cost. A short call on a line with a large brief and a full knowledge block re-bills all of it on every turn, while a longer call on a lean profile carries less each time. Shrinking the brief is usually the biggest single lever.
Does a silent call cost anything?
Yes. A call that connected and reported no tokens is charged from its duration, and a row left active is charged by the sweep when it closes. The only calls that cost nothing are the ones that were refused before anything was opened.
Can a customer workspace see its own per-call cost profile?
The detailed profiler is operator-only. A customer workspace sees its usage through the ordinary usage surfaces rather than the per-call ledger — the same split that applies to every other cost in the platform.