Skip to main content
All events share the envelope; data.object is always "call" and data.call is the call object below — the same shape as GET /v1/calls/{id}. analysis and custom_analysis are always fields on the call (null until they’re ready); the transfer event additionally attaches a transfer sub-object. Current API version: 2026-08-01

The call object

Present as data.call on every event. It’s the same object as GET /v1/calls/{id} — one shape to learn across REST and webhooks. cost, analysis, and custom_analysis are null until they’re finalized post-call (so call.started / call.ended carry null for them; they’re populated by the later analysis/processing events).
string
The call id (matches execution_id from POST /v1/calls).
string | null
The agent that ran the call.
string
Lifecycle status.
string
inbound or outbound.
string | null
Caller number.
string | null
Destination number.
integer | null
Connected duration.
string
When the call was created (ISO 8601, UTC).
string | null
When it connected.
string | null
When it ended.
object | null
Your passthrough JSON from POST /v1/calls.
object | null
The call’s dynamic/custom variables — from POST /v1/calls variables, or resolved for inbound (e.g. caller_no). Only your custom variables, not internal runtime state.
object | null
{ currency: "USD", total, rate_per_min }null until billed.
object | null
{ sentiment, outcome, language, summary }null until analyzed.
object | null
Your configured custom-analysis data.
object
The conversation.
string | null
Stable recording URL; null until ready.

Call started

call.started — the call was placed and is dialing/ringing. Cost, transcript, and recording are not yet available.

Call transfer updated

call.transfer.updated — a human-transfer state changed. Adds a transfer sub-object:

Call ended

call.ended — the call reached a terminal status. The core outcome event, with transcript, timings, and cost.

Call recording ready

call.recording.ready — the recording is available. In addition to the stable recording_url, each delivery carries a ready-to-use, expiring download link, minted fresh for each delivery:

Call analysis completed

call.analysis.completed — platform AI analysis finished. The call’s analysis field is now populated (same shape as the REST analysis field):

Call custom analysis completed

call.custom_analysis.completed — your configured custom-analysis items finished. The call’s custom_analysis field is now populated (the extracted business data):

Call processing completed

call.processing.completedthe recommended default subscription. A fan-in event that fires once analysis, custom analysis, and the recording are all terminal — the complete record in a single payload (call object + analysis + custom_analysis). Subscribe to this if you want one clean event per finished call instead of stitching the individual ones together.
Subscribe to call.processing.completed for the full record in one event, or to call.ended if you need the outcome the instant the call hangs up (before analysis/recording are ready).