Reference: every close_reason value, its bucket, its close_reason_label sentence, whether the platform fee is waived, and what to do.
close_reason is how a call or chat ended. It is on the call record, in the session.completed webhook, a filter on GET /v1/calls?close_reason=…, and, grouped into buckets, in the observability endings and close_reason_data. Every surface also returns close_reason_label, the sentence shown below; display that instead of mapping strings yourself.
user_initiated means the agent hung up (an end_call operation), not the caller. The caller hanging up is participant_disconnected.
The platform fee is waived when the reason ends in _failed or 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. Every other reason, and a missing one, is charged. Provider cost is always yours. Bucket and fee are independent: avatar_disconnected is a platform fault and still charged. See costs.
The agent finished what it was doing and ended the call
charged
Nothing.
end_call
The agent ended the conversation
charged
A chat ended by an end_call operation.
api_end
Ended through the API
charged
A chat ended by POST /v1/chats/{chat_id}/end.
replaced
A newer chat with this contact took its place
charged
A new chat started for the same contact (on WhatsApp or Telegram, any agent), an outbound post or batch chose another agent, or the channel trigger now names another agent.
messages_off
Messages were turned off on this number
charged
A WhatsApp or Telegram chat whose messages trigger was turned off or deleted; no more of their messages would arrive.
inactivity_timeout
They stopped writing, so the chat ended after 24 hours
charged
A chat whose person sent nothing for 24 hours. Give the agent end_call to end chats when the conversation is done.
silence_timeout
The caller stayed silent, so the agent said goodbye and hung up
Set from the carrier’s SIP response to an outbound dial, except voicemail. A call batch re-dials these when max_attempts allows, except sip_declined_failed and sip_unallocated_failed, which it never re-dials.
Ten consecutive batch calls ending in carrier_fault, configuration, platform or other stop a call batch (batch.failed). caller_unreachable never counts.
Reason
Label
Fee
What to do
sip_dial_failed
The outbound call could not be dialled
waived
The carrier refused with no recognised code. Check credentials and the number’s caller ID.
Any reason not listed above is bucketed other and shown raw; its label is the reason de-underscored and capitalized (some_new_reason → Some new reason). Reasons you may see here include sip_client_initiated_failed (The caller’s phone ended the call), sip_user_rejected_failed (The call was declined) and sip_unknown_reason_failed (The phone leg dropped for an unknown reason). A terminal session with no reason reads No ending was recorded.
A chat ends with end_call, api_end, replaced, messages_off or inactivity_timeout, all normal, and is charged per answered message whichever way it ended. See text conversations.