total_charge is the two added together, and it exists so you can see a call’s
full economics in one figure. Only the platform fee is ever debited from your
credit balance. Debiting the provider cost would charge you a second time for
spend that already went onto your own key — which is what strict
bring-your-own-key means here. See provider keys.
The platform fee
It is prorated by the second, not rounded up to a whole minute: a 90-second
voice call is charged $0.00525.
Text carries no platform fee. A text session is an idle conversation window
rather than a stretch of talking, so a per-minute charge there would bill how
promptly your customer replies rather than anything the agent did. A text
conversation costs your workspace only what its own LLM key was charged.
The rate is decided by the channel the session ran on, and nothing else. Avatar
time on a video call is provider cost on your own key, on top of this fee, not
part of it.
The fee is waived on a failed call
A call that failed keeps its provider cost — the providers ran and charged you regardless — and is charged no platform fee. A close reason counts as failed if it ends in_failed, or if it is one of:
error, stale, job_shutdown, job crashed, orphaned, unknown,
avatar_start_failed, invalid_dispatch_metadata, missing_dispatch_metadata,
unknown_tenant, missing_published_definition, rejected,
insufficient_credits.
Everything else is a normal completion and is charged the fee — including a
call with no close reason at all, and including transferred, which is a
successful escalation rather than a failure. There are no substring heuristics:
a reason with “error” in the middle of it is not a failure unless it is on this
list. See close reasons.
The five metered kinds
Every provider charge on a call is one of five kinds, and each is priced from the catalog entry of the exact model that ran.
A call fills either
llm + stt + tts or realtime — never both, because
the agent ran one pipeline or the other. Avatar sits beside whichever it ran.
Two flags qualify an LLM line rather than being a kind of their own:
purposeisconversationoranalysis. Post-call analysis prices through exactly the same path as the call, so without this its cost would fold invisibly into the call’s own LLM line.prioritysays the line ran in the provider’s priority lane, which prices at a different rate block on the same catalog entry. It is the reason one LLM line can cost double the standard rate. See priority lane.
Reading cost on one call
GET /v1/calls/{session_id} returns cost:
The snapshot is never re-derived from today’s catalog. A rate that changes next
month does not move what an old call says it cost.
Reading cost across the workspace
GET /v1/observability returns a cost section over the range, for up to seven
days at a time.
GET /v1/calls/stats is the smaller question — total_spend and
avg_cost_per_call over priced_calls, for a window that defaults to the last
30 days. See calls.
Agent task runs are not in any of this. A task is an agent nobody talks to;
it writes no session row, so neither its runs nor its spend reach the
observability endpoint or the calls list. Task spend appears on the task’s own
run history, and — for a task drafting an email campaign — on that batch’s page.
See running tasks.
The credit ledger
GET /v1/billing/credits/ledger is every movement of this region’s balance,
newest first, with what caused each. GET /v1/billing/credits is the balance
itself, plus what it buys at today’s rates.
Every entry carries
amount (signed — a usage row is negative),
balance_after, and created_at.
Three consequences of the ledger holding only the platform fee:
- A text session writes no ledger row at all. Its fee is zero, and a row saying “we took nothing” is noise in a statement you have to read.
- A failed call writes none either, for the same reason.
- A session is debited exactly once, ever. Re-pricing a call — which is what backfilling analysis does — cannot debit it twice. The fee is a function of duration and channel alone, so a re-price could not change the amount anyway. What a re-analysis does grow is your own provider bill, on your own key.
Running out
The check isbalance > 0 and nothing more — no reservation, no forecast of
what a call might cost. It runs when you start a web call, place an outbound
call, dial a batch recipient, or take an inbound SIP call.
At zero, starting a new call is refused with HTTP 402:
This workspace is out of credits. Add credits in Settings → Billing to start new calls. Calls already in progress are unaffected.An inbound call refused this way is recorded with
close_reason: insufficient_credits, and is never itself charged the fee it was refused for
lacking.
A call already running is never interrupted. Because of that the balance can end
a call slightly negative from that call’s own fee, and the next top-up pays the
debt off first. An outbound batch that runs out pauses without failing and
without spending an attempt, and resumes on its own when you top up.
See pricing and credits for packs, checkout
and the low-balance warning.
In the dashboard
The call detail page has a Cost section: a proportion bar of where the provider cost went, then one row per priced line — kind, provider, model, the exact quantities and the rate each was charged at — withpriority and
analysis tagged on the lines they apply to. Under them sit provider cost, the
platform fee with its formula ($0.0035/min × 4m 12s, or waived — the call failed), and the total.
Money is shown to six decimal places throughout, because a real line can cost
$0.000762 and anything shorter rounds it to nothing.
Pricing and credits
Packs, checkout, the signup grant and the zero-balance rules.
Provider keys
Which providers you bring a key for, and what fails without one.