close_reason is the most specific fact Talqing holds about how a run ended. It appears on the call record, in the session.completed webhook, as a filter on GET /v1/calls, and — grouped into buckets — on the observability endings chart. Every surface also serves close_reason_label, the plain sentence for that value. Read it rather than mapping the strings yourself: there are more than fifty of them, written from five places, and a second copy of the list goes stale the first time one is added.
user_initiated means the agent ended the call, not the caller. The name comes from the underlying media stack, where it identifies whoever asked for shutdown — and on this platform that is only ever the end_call operation. The caller hanging up is participant_disconnected. Reading user_initiated at face value gets the actor exactly backwards, and it is the single most common misreading of this field.

The buckets

A bucket answers “who owns the fix”. It never replaces the reason — every surface keeps the raw string beside it. They are ordered as above on every chart: what went right, then outward through the parties who could fix what went wrong.

The fee column

waived means the platform fee was not charged for that call. Provider cost is still yours — the providers ran and billed your key regardless. See costs. Note that the bucket and the fee are not the same question. Three reasons in the platform bucket are still charged the fee, and they are marked below.

normal

transferred

caller_unreachable

Every reason here is read off the carrier’s own SIP response to an outbound dial. None of them is a fault in your agent.

carrier_fault

A run of these across different numbers is a trunk problem, not a phone list — which is why they count toward an outbound batch’s circuit breaker, and a run of busy signals does not. Ten consecutive failures from this bucket, configuration, platform or other stop the batch. See batch calling.

configuration

These are yours to fix, and every one of them is fixable.

platform

Ours. Every one of these is a call you paid for in reputation, and the three marked charged are ones where the platform fee was still taken — the fee waiver list and this bucket are separate questions and not copies of each other.

other

Not a list. other is what a reason this reference does not name buckets as, and the raw string is shown beside it rather than being folded into a generic label. That is deliberate: a default that absorbed a new failure would make it invisible until somebody remembered to update the mapping. A reason with no sentence of its own is de-underscored and capitalized — so an unrecognised some_new_reason reads as Some new reason. A terminal call that recorded no reason at all reads as No ending was recorded.

Text conversations

A text session is a window rather than a call, and three reasons are its normal endings: orphaned and session_replaced also occur on text. See text conversations.

Filtering by reason

GET /v1/calls?close_reason=… takes the exact string.
To see them ranked rather than filtered, read endings from GET /v1/observability — every distinct reason in the range with its bucket, its session count and how many of those failed. See observability.