Call Lifecycle
What happens from POST /v2/calls to the finished record — every stage, which status you see, and exactly when each field becomes readable.
This page traces one outbound call from the API request to the fully-populated record. Inbound calls join at the ringing stage; everything after that is identical.
The flow
Stage by stage
- Accepted.
POST /v2/callsvalidates and answers201withstatus: "queued"— or, withscheduled_at,202withstatus: "scheduled". Nothing has dialled yet. - Scheduled calls wait, and re-check the window. At fire time the agent's
Calling Window is evaluated again; a call whose window has closed moves to
rescheduledand is booked for a time inside the next open window rather than rejected — spread across the window, not stacked on the minute it opens, so a night's worth of deferred calls does not all ring at once. - Dialling. The call is handed to the telephony network:
initiated, thenringing. A call nobody answers ends here asno-answerorbusy. - Conversation. On answer the status is
in-progressand the voice pipeline runs — transcription, the agent's reasoning, speech synthesis — one loop per conversational turn. - Hangup ⇒ terminal status, immediately. When the call ends — whoever
ended it, and why, is the subject of Hangups &
Termination — the status moves straight to its terminal
value and
is_terminalbecomestrue. There is no intermediate "post-processing" status. - Enrichment continues after the status is terminal. Transcript assembly, cost, the recording and analysis land in the seconds that follow.
- The webhook fires when everything has landed. The
all_processing_completedevent waits on all of it and carries the full 47-field record — withprocessing_incompleteandmissing_fieldsnaming anything that never arrived.
Terminal means the call is over — not that every field has landed
This is the one place this platform differs from the pattern many
integrations expect. is_terminal: true the moment the line drops; cost,
recording_url and transcript may still be null on that same read. If you
poll, stop on is_terminal and the field you need being non-null. If
you can, don't poll — the consolidated webhook exists precisely so you never
have to guess when enrichment finished.
When each field becomes readable
| Field | Available |
|---|---|
status, is_terminal | Immediately at every stage. |
duration_seconds | At hangup, from the carrier — the carrier figure is authoritative. |
transcript | Seconds after hangup, once assembly completes. GET /v2/calls/{execution_id}/transcript answers status: "unavailable" while it is pending — never a 404. |
cost | When billing runs, shortly after hangup. null means not yet billed; 0.0 means billed at zero (a voicemail, for example). |
recording_url | When the recording is stored. A call that was never answered produces none. |
summary, analysis | When post-call analysis completes. |
| per-turn timings | With the same report that carries the transcript. See Execution Logs. |
A canceled call that never dialled is the one case where these fields never
arrive: nothing was placed, nobody was rung, and no minutes are billed.
Statuses
The full fifteen-value enum, the terminal / in-flight / failure sets, and the spelling rules live on Errors & Statuses. The webhook's own nine-value vocabulary is on Webhook Payloads.

