EndedReason
Why a Call ended. dial_failed and no_answer (1.16.0) end an outbound phone Call: the carrier refused the dial, or the callee did not answer before the join deadline. canceled (1.19.0): POST /v1/calls/{call_id}/end ended the Call, before or during the conversation. worker_lost (1.19.0): the api's sweeper ended the Call because its worker had signalled and then sent none, so the lease lapsed: each signal renews the Call's lease by SIGNAL_LEASE_S, 30 seconds in the api as built (a target), and the api's sweeper, which runs every VOCAL_SWEEP_INTERVAL_S, 5 seconds by default (a target), ends the Call at the next sweep after the lease has lapsed; both are the api's values, set in the api and not by this contract; only the api sets it, and a late finalize from that worker may replace it once. Versions 1.19.0 to 1.34.0 named a lease of 60 seconds and a reaper every 30 seconds, which are not the api's values. finalize_failed (1.21.0): the api could not apply the finalize request of the worker for a reason a retry cannot fix, such as a body that failed validation or a constraint that refused it, so it stored the request as a dead letter, ended the Call with this reason and released its reservation; only the api sets it, and an operator replays the stored request with the replay_call_finalize command. The refused_* reasons (1.22.0, FR-telephony-4) end an inbound phone Call that admission refused: the api records the Call ended at once, never answered and with no Turns, and the worker plays the refusal announcement and hangs up. refused_suspended: the Organization is suspended (org_suspended); refused_spend_cap: its monthly spend cap is reached (spend_cap_reached); refused_concurrency: it is at its concurrent Call limit (concurrency_limit_reached); refused_no_route: the Phone number routes to no Agent version that can take a live phone Call, because it routes to no Agent, the Agent has no published version to run, or the version runs on mock Providers. A call to a number that is unknown or not active belongs to no Organization that can take it, so it is not recorded. Only the api sets these reasons. recording_announcement_failed (1.32.0, workspace ADR 0082): the recording announcement a recorded Call requires could not be spoken, because its rendered line still held a tag, its utterance failed to schedule or its synthesis did not end whole; the Session ended before any other speech, so no caller audio was stored. disclosure_failed (1.32.0): the AI disclosure the Call requires could not be spoken, because its rendered script still held a tag or its utterance failed to schedule; a worker before 1.32.0 ended such a Session dispatch_failed. The worker sets both. refused_unpriced (1.38.0, workspace ADR 0086): admission refused an inbound phone Call because the pinned Agent version names a reference, primary or Agent secondary, whose model has no vendor list price above 0 in force at the admission instant (409 agent_version_unavailable), or because the carrier minute of the leg has none (422 capability_not_available); only the api sets it. stage_unpriced (1.38.0): the worker ended the Session before the greeting because a stage of stt, llm or tts kept no entry whose every unit has a SessionPrice that is vendor and above 0 (or none for a mock Provider); an absent prices counts as every price absent. policy_load_failed (1.48.0, roadmap slice 2.2): the worker ended the Session before on_call_start because it could not load the Policies of its configuration (SessionConfig.policies): a version recorded under an engine the worker does not run (rules_engine_version_mismatch), or a document its load check refuses (rules_node_type_not_allowed, rules_too_large or rules_syntax_error); the warnings of the finalize request carry the code, and no Policy was evaluated. Dispatch never sends such a configuration, so the reason names a defect. policy_end_call (1.49.0): the end_call action of a Policy ended the Call, after its line was spoken; the policy.fired event of the firing names the Policy version and the reason code of the action. The worker sets it; a worker on 1.48.0 ended such a Call agent_hangup. transferred (1.50.0, roadmap slice 2.4, FR-telephony-6): a cold transfer completed, the caller handed over by SIP REFER to a destination of the transfer allowlist; the Call event call.transferred names the transfer, whose context note GET /v1/calls/{call_id}/transfers/{transfer_id} reads. The worker sets it. machine_detected (1.50.0, FR-calls-12): answering-machine detection decided machine and on_machine is hang_up. voicemail_left (1.50.0): it decided machine, on_machine is leave_message, and the message was spoken after the beep or the end of the greeting. The worker sets both, and the answering_machine of the Call holds the decision. pre_call_declined (1.52.0, roadmap slice 2.7, FR-dispatch-7): the pre-call hook declined the Call, or failed under on_failure: decline, before any room or dial; the reservation is released and an inbound caller hears the refusal announcement of the Phone number or reaches its fallback line. Only the api sets it, and call.ended carries the reason code of the decline. workflow_complete (1.58.0, roadmap slice 2.12): the authored machine entered a final state and the Session ended the Call after its closing speech (statecharts-and-squads.md section 10.6); the worker sets it, and the Workflows of roadmap slice 2.13 will end with it too. prompt_compose_failed (1.58.0, phase-2-status.md F25 item 2): the worker could not compose the prompt layers of the claimed Session (prompt_missing, prompt_section_invalid or prompt_variant_missing) and ended it before any Provider opened, where it ended dispatch_failed before; the worker sets it. max_turns (1.58.0, F26 item 12): an evaluation Call reached the max_turns of its scenario, where it was recorded max_duration before; the headless Engine sets it. refused_opted_out, refused_destination and refused_compliance (1.61.0, roadmap slice 2.15): the start job of a scheduled Call, or of a retry, ran admission and it refused: the destination is opted out of voice (contact_opted_out), the dial policy refused the destination (dial_not_allowed), or the compliance gate refused the pinned version (environment_not_allowed, provider_not_allowed); the other refusals at a start job end the Call with the refused_* reasons of 1.22.0 and 1.38.0, and the Call event call.refused names the admission code. schedule_expired (1.61.0): the window of a scheduled Call did not open before its expires_at. Only the api sets these four. busy (1.61.0): the callee of an outbound phone Call answered busy; the worker sets it, and a worker before 1.61.0 ended such a Call dial_failed or no_answer. From 1.62.0, decided: a dialled leg that LiveKit SIP ends with a SIP 486 Busy Here, 600 Busy Everywhere or 603 Decline, or with the disconnect reason USER_REJECTED that carries no status, ends the Call busy, since declined is the reason of a rung app Call, which joins with Client apps; the worker sends it only to an api whose contracts_version is 1.61.0 or later. From 1.64.0, decided: a dial that LiveKit SIP refuses before the leg joins the room is ended by the api, the plane whose dial request receives the refusal, busy for a SIP 486, 600 or 603 and dial_failed for any other status, with the status recorded either way; the worker ends busy only a leg it saw leave with USER_REJECTED. A reader on an older version does not know a reason added after it and must take the version that added it first: 1.21.0 for finalize_failed, 1.22.0 for the refused_* reasons, 1.32.0 for recording_announcement_failed and disclosure_failed, 1.38.0 for refused_unpriced and stage_unpriced, 1.48.0 for policy_load_failed, 1.49.0 for policy_end_call, 1.50.0 for transferred, machine_detected and voicemail_left, 1.52.0 for pre_call_declined, 1.58.0 for workflow_complete, prompt_compose_failed and max_turns, 1.61.0 for refused_opted_out, refused_destination, refused_compliance, schedule_expired and busy.
An enumeration of 37 values.
Values
caller_hangupagent_hangupmax_durationsilence_timeoutprovider_errortransport_lostworker_drain_timeoutdispatch_failednot_claimednot_joineddial_failedno_answercanceledworker_lostfinalize_failedrefused_concurrencyrefused_suspendedrefused_spend_caprefused_no_routerecording_announcement_faileddisclosure_failedrefused_unpricedstage_unpricedpolicy_load_failedpolicy_end_calltransferredmachine_detectedvoicemail_leftpre_call_declinedworkflow_completeprompt_compose_failedmax_turnsrefused_opted_outrefused_destinationrefused_complianceschedule_expiredbusy