> ## Documentation Index
> Fetch the complete documentation index at: https://docs.hubtalk.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Call outcomes: `call_status` and `status_reason`

> The outcome axis: buckets, the reasons inside them, and how they fold into a verdict.

# Call outcomes: `call_status` and `status_reason`

**`call_status`** — final status bucket of a finished call (empty string until finalized). One axis, one source of truth; quality (`call_successful`) and technical reliability (`health`) are separate axes and never leak into the status:

| Value           | Meaning                                                                                                                                                                             |
| --------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `completed`     | the call connected and finished (in any way)                                                                                                                                        |
| `not_connected` | an outbound call never connected                                                                                                                                                    |
| `error`         | the platform could not carry the call through: a connected call was dropped by a platform failure, the agent never joined, or the outcome was never finalized (details in `health`) |

**`status_reason`** — fine-grained reason, always belonging to exactly one bucket:

| Bucket          | Value                                   | Meaning                                                                                                                                                                             |
| --------------- | --------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `completed`     | `agent_hangup`                          | Conversation ran to the end of the agent's flow.                                                                                                                                    |
| `completed`     | `user_hangup`                           | Callee spoke but hung up before the flow finished.                                                                                                                                  |
| `completed`     | `no_speech`                             | Call connected but no recognizable callee speech.                                                                                                                                   |
| `completed`     | `too_short`                             | Below the agent's configured minimum turns/duration.                                                                                                                                |
| `completed`     | `voicemail_reached`                     | Answering machine detected (check `message_left`).                                                                                                                                  |
| `completed`     | `max_duration_reached`                  | Auto-ended at the agent's maximum call duration.                                                                                                                                    |
| `completed`     | `silence_timeout`                       | Auto-ended after prolonged callee silence.                                                                                                                                          |
| `completed`     | `transferred_cold` / `transferred_warm` | Call successfully handed off; the AI left the conversation.                                                                                                                         |
| `completed`     | `observer_incident`                     | Auto-ended by a compliance observer's end-call reaction.                                                                                                                            |
| `completed`     | `platform_shutdown`                     | The platform ended the call while stopping for an update.                                                                                                                           |
| `not_connected` | `no_answer`                             | The subscriber's phone rang and nobody picked up within the ring window.                                                                                                            |
| `not_connected` | `busy`                                  | Destination busy.                                                                                                                                                                   |
| `not_connected` | `user_declined`                         | Callee explicitly declined the call.                                                                                                                                                |
| `not_connected` | `invalid_destination`                   | Nonexistent or invalid number.                                                                                                                                                      |
| `not_connected` | `trunk_auth_failed`                     | SIP trunk authentication failed.                                                                                                                                                    |
| `not_connected` | `provider_unavailable`                  | The call never reached the subscriber: telephony did not answer in time or refused, and there was no ringing.                                                                       |
| `not_connected` | `sip_routing_error`                     | SIP routing failure.                                                                                                                                                                |
| `not_connected` | `spam_blocked`                          | Blocked as spam by the carrier.                                                                                                                                                     |
| `not_connected` | `dial_failed`                           | Generic dial failure (no finer detail available).                                                                                                                                   |
| `not_connected` | `cancelled_by_function`                 | A pre-dial function of the agent decided not to place the call.                                                                                                                     |
| `not_connected` | `cancelled_by_operator`                 | The dial was stopped by an outside command before it connected — the cabinet button or `POST /v1/calls/{id}/end`. Neither the contact attempt nor the frequency cap is spent on it. |
| `error`         | `internal_error`                        | Platform failure on a connected call — see `health` / `health_reasons`.                                                                                                             |
| `error`         | `agent_unavailable`                     | The voice agent never joined the call.                                                                                                                                              |
| `error`         | `not_finalized`                         | The outcome was never recorded; `duration` is `null`.                                                                                                                               |

<Warning>
  **`busy` and `user_declined` are distinct reasons.** `busy` means busy and `user_declined` means the subscriber actually declined the call. If you build reports on dial-failure reasons, separate the two values rather than folding them into one.

  A second consequence for retry logic on your side: **whether a reason is permanent depends on the market**. `user_declined` closes a number for good only on the US profile; on other profiles it is transient, and the number returns to dialing having spent an attempt. The campaign launch check refuses an `expert` rule that retries a permanent outcome (`rule_permanent_retry`).
</Warning>

**`health_reasons`** — codes explaining a `warning`/`error` health verdict. A call's verdict is the worst code that fired: any error-level code makes the call `error`, otherwise `warning`. The vocabulary is open — new codes are added over time, so treat an unfamiliar one as data, not as a parsing failure.

Codes come from four sources. The split matters: **`health_reasons` carries the output of a rule, never its input** — `status_reason` values and the internal codes of call events never appear here.

**1. Call events** — something went wrong inside the conversation:

| Code                    | Level   | When                                                                     |
| ----------------------- | ------- | ------------------------------------------------------------------------ |
| `llm_execution_failed`  | error   | the execution model did not answer and the agent spoke its fallback line |
| `llm_role_failed`       | warning | a model in a supporting role did not answer                              |
| `llm_retry`             | warning | the answer came from the fallback model                                  |
| `context_overflow`      | error   | the model's context overflowed                                           |
| `tts_unspoken`          | error   | synthesis failed and the line was never spoken                           |
| `tts_error`             | warning | a synthesis failure the call recovered from                              |
| `tts_fallback`          | warning | switched to the reserve voice                                            |
| `asr_turn_lost`         | error   | the caller's turn was lost by recognition                                |
| `asr_error`             | warning | a recognition failure that lost no turn                                  |
| `realtime_error`        | error   | a failure in realtime (speech-to-speech) mode                            |
| `noisy_line`            | warning | the line was noisy: the call ran, recognition did not                    |
| `transfer_failed`       | error   | the transfer broke down                                                  |
| `transfer_ring_timeout` | warning | the destination did not answer and the fallback edge ran                 |
| `observer_error`        | warning | the compliance observer failed                                           |
| `normalizer_degraded`   | warning | the pre-TTS normalizer did not answer                                    |
| `lang_detect_degraded`  | warning | language detection did not answer                                        |
| `rag_degraded`          | warning | a knowledge base lookup failed                                           |
| `token_budget_degraded` | warning | the context was trimmed to the token budget                              |
| `tool_failed`           | warning | a function or code node returned an error                                |
| `silence_timeout`       | warning | auto-ended on caller silence                                             |
| `max_duration`          | warning | auto-ended on maximum call duration                                      |

**2. The call status axis** — `status_reason` values fold into these:

| Code                | Level   | From which `status_reason`                                       |
| ------------------- | ------- | ---------------------------------------------------------------- |
| `disconnect_error`  | error   | `internal_error`, `not_finalized`, `agent_unavailable`           |
| `dial_infra_failed` | error   | `trunk_auth_failed`, `provider_unavailable`, `sip_routing_error` |
| `dial_failed`       | warning | every other reason in the `not_connected` bucket                 |

Reasons that belong to the callee (`no_answer`, `busy`, `user_declined`, `invalid_destination`, `spam_blocked`) and dials you cancelled yourself before dialing (`cancelled_by_function`, `cancelled_by_operator`) contribute **nothing**: they are not platform defects.

**3. Post-call analysis** — `analysis_skipped`, `analysis_failed`, `analysis_interrupted`, all warning level, from the terminal state of the analysis.

**4. Recording and timing** — `recording_head_lost` (part of the recording does not exist) and `slow_turns` (the 90th percentile of turn duration is above the configured threshold), both warning.
