disconnection_reason on the call object says why a call ended. The values are defined by DISCONNECTION_REASONS in packages/shared (42 values). The field is null while a call is registered or ongoing.
You can filter on it in Call history, in analytics charts, in QA cohorts and with filter_criteria.disconnection_reason on list-calls. Analytics charts and dashboards break calls down by it.
How it maps to call_status#
A call that never started ends as not_connected when its reason is one of the connection failures marked not_connected below. Every other ending is ended. A call that could not be placed at all (the media room could not be prepared) is stored with call_status: error and dial_failed.
Post-call analysis treats dial_busy, dial_failed, dial_no_answer, invalid_destination, concurrency_limit_reached, voicemail_reached, and any reason starting with error, as unsuccessful in mock mode, and sets in_voicemail to true only for voicemail_reached. See Post-call analysis.
Normal endings#
| Value | Set when |
|---|---|
user_hangup |
The caller left the room or hung up. Also used when the API closes a call whose runtime stopped reporting, if the call was ongoing or inbound. |
agent_hangup |
The agent ended the call (an end call tool or end node). |
call_transfer |
The agent transferred the call to another number, or an inbound call over the concurrency limit was transferred to the number's fallback number. |
voicemail_reached |
Voicemail detection found an answering machine and the agent's voicemail action ran. |
ivr_reached |
IVR detection found a phone menu and the agent has an ivr_option, so it hung up. |
inactivity |
Nobody spoke for longer than the silence policy allows after the reminders were used. |
max_duration_reached |
The call hit the agent's max_call_duration_ms. |
manual_stopped |
You ended the call with POST /v2/stop-call/:call_id or End Call in Live Monitoring. |
user_requested_dnc |
DNC detection is on (enable_dnc_detection), the caller asked not to be called and confirmed. The linked contact is marked Do not call. |
scam_detected |
The guardrails flagged the caller as a scam. The agent says the guardrail fallback message and hangs up. |
guardrail_triggered |
Guardrails blocked 3 turns (input or output) in one call. |
call_take_over |
A dashboard user took over the call in Live Monitoring. The value is kept when the call later ends for another reason. |
Transfer agent endings#
These are set on calls handled by a transfer agent (is_transfer_agent) during an agentic warm transfer.
| Value | Set when |
|---|---|
transfer_bridged |
The transfer agent connected the caller to the transferee (the bridge transfer tool, or the transferee's voicemail with a bridge_transfer voicemail action). |
transfer_cancelled |
The transfer agent cancelled the transfer (the cancel transfer tool). |
Connection failures#
All of these lead to call_status: not_connected when the call never started.
| Value | Set when |
|---|---|
dial_busy |
SIP 486 or 600 on an outbound dial, or a busy error from the carrier. |
dial_no_answer |
SIP 408, 480 or 487, or a dial timeout. Also used when the API closes an outbound call that never reported back. |
user_declined |
SIP 603. |
marked_as_spam |
SIP 608. The phone number is also flagged as spam in Phone Numbers. |
invalid_destination |
SIP 400, 404, 410, 484, 485 or 604, or a not-found error. |
telephony_provider_permission_denied |
SIP 401, 403 or 407. |
telephony_provider_unavailable |
SIP 502, 503 or 504. |
dial_failed |
Any other dial failure, or the call could not be placed. |
sip_routing_error |
No outbound trunk for the number, or register-phone-call SIP routing is not configured. |
registered_call_timeout |
A register-phone-call call was not dialled within 5 minutes. |
error_user_not_joined |
A web call's browser never joined the room. |
concurrency_limit_reached |
No concurrency slot was free: an inbound caller waited in the queue and the fallback transfer did not happen, or a registered call could not be admitted. |
no_concurrency_fallback |
No slot was free for an inbound call and the number has no fallback number. |
no_valid_payment |
A batch call could not be dialled because the workspace has no credit. The attempt is kept as a call so it shows in the batch results. |
A failed outbound dial also stores the carrier error text in metadata.dial_error.
Errors#
| Value | Set when |
|---|---|
error_llm |
The LLM (or a speech-to-speech model) failed and the call could not continue. |
error_asr |
Speech to text failed. |
error_tts |
Text to speech failed. |
error_unknown |
Any other runtime failure, or the API closed a call with no better reason. |
error_llm_websocket_open |
A custom LLM agent could not open its WebSocket, or has no llm_websocket_url. |
error_llm_websocket_lost_connection |
The custom LLM WebSocket closed and reconnects were used up. |
error_llm_websocket_runtime |
The custom LLM WebSocket raised an error during the call. |
error_llm_websocket_corrupt_payload |
The custom LLM server sent a frame Tried could not parse. |
See Custom LLM for the WebSocket protocol.
Defined but not set on calls#
These values are in the enum so payloads stay compatible, but Tried does not currently write them to a call:
| Value | Note |
|---|---|
credit_exhausted, budget_reached |
When credit is used up or the monthly budget is reached, the API refuses the request with HTTP 402 and error_code set to one of these values. No call record is created. |
user_requested_callback |
Not emitted. |
error_no_audio_received |
Not emitted. |
network_blocked |
Not emitted. |
error_retell |
Not emitted. |
Gotchas#
- The first reason recorded is kept. If the agent hangs up and the caller's hang-up arrives a moment later, the call stays
agent_hangup. - In the text simulator, a call the agent does not end itself ends with
user_hangup, ormax_duration_reachedwhen it hits the simulation limit. - Alerting's Transfer call failures metric counts calls that called a transfer tool but did not end with
call_transfer. See Alerting.