> For a complete index of all SignalWire documentation pages, fetch https://signalwire.com/docs/llms.txt

# AI debug webhook

POST 

A diagnostic feed for a call that is still in progress. Set `debug_webhook_url` on your agent and
every step it takes is posted to that URL as it happens: speech recognized, model called, tool
invoked, context switched, error hit. Use it to work out why a call went the way it did — which
tool the agent reached for, what came back, where a turn went wrong — or to react while the call is
still live, such as paging a supervisor.

Each request carries `call_info` plus one or more event properties, where the property name is the
event. One moment can produce several: evaluating a `data_map` webhook sends `webhook`, `input`,
`output`, `error_keys`, and `match` together. Handle the properties you recognize and ignore the
rest, since the set grows over time.

Setting the URL is what enables the feed. `debug_webhook_level` only widens it: at `2` it also
carries `conversation_add`, `llm_request`, and `llm_response`, which fire on every turn and every
model call.

Reference: https://signalwire.com/docs/apis/rest/webhooks/ai-debug-webhook

## Request

### Payload

- `call_info` (object, required) — Identifies the call the event came from.
  - `call_id` (string, required) — ID of the call.
  - `content_type` (string, required) — The content type of the POST body. Always `text/json`.
  - `content_disposition` (string, required) — How the body is delivered. Always `post_data`.
  - `conversation_type` (string, required) — The conversation type. Always `voice`.
  - `project_id` (string, optional) — Your project ID.
  - `space_id` (string, optional) — Your Space ID.
- `session_start` (object, optional) — The AI session started. Sent once per session. The fields differ by session type: a standard session reports the voice it will use, while a speech-to-speech session reports `mode` as `oart` along with its audio settings and reports no voice at all. Every field is optional, so read `mode` to tell which kind of session you have.
  - `model` (string, optional) — The model the agent is running. `unknown` on a speech-to-speech session with no model set.
  - `tts_engine` (string, optional) — The text-to-speech engine. Standard sessions only, and only when a voice is configured.
  - `tts_voice` (string, optional) — The text-to-speech voice. Standard sessions only, and only when a voice is configured.
  - `language` (string, optional) — The language code the session started in. Standard sessions only, and only when a voice is configured.
  - `mode` (string, optional) — Always `oart` when present, marking a speech-to-speech session. Absent on a standard session.
  - `rate` (integer, optional) — The audio sample rate, in hertz. Speech-to-speech sessions only.
  - `audio_format` (string, optional) — The audio encoding. Speech-to-speech sessions only.
  - `tool_model` (string, optional) — The separate model used for tool calls. Speech-to-speech sessions only, and only when one is configured.
  - `local_vad` (boolean, optional) — Always `true` when present, meaning voice activity detection runs on the media rather than at the model. Speech-to-speech sessions only.
- `session_end` (object, optional) — The AI session ended. Sent once per session.
  - `reason` (enum, required) — Why the session ended. `normal` on an ordinary finish, `hard_timeout` when it hit its configured time limit, and `end_call` or `error` on a speech-to-speech session that was hung up or failed.
    - Allowed values: `normal`, `hard_timeout`, `end_call`, `error`
  - `duration_ms` (integer, required) — How long the session ran, in milliseconds.
  - `input_tokens` (integer, required) — Input tokens the session consumed.
  - `output_tokens` (integer, required) — Output tokens the session produced.
  - `ended_by` (string, optional) — Who or what ended the call, `system` when nothing recorded it. Absent on a speech-to-speech session.
  - `fatal_error_reason` (string, optional) — A description of the error. Included only when the session ended on one.
- `startup_hook` (object, optional) — Your `startup_hook` function finished, whether or not it succeeded.
  - `duration_ms` (integer, required) — How long the hook took, in milliseconds.
  - `success` (boolean, required) — Whether the hook ran successfully.
  - `error` (string, optional) — Why the hook failed. Included only when `success` is `false`.
- `hangup_hook` (object, optional) — Your `hangup_hook` function finished, whether or not it succeeded.
  - `duration_ms` (integer, required) — How long the hook took, in milliseconds.
  - `success` (boolean, required) — Whether the hook ran successfully.
  - `has_fatal_error` (boolean, optional) — Whether the session ended on an unrecoverable error. Included only when the hook succeeded.
  - `error` (string, optional) — Why the hook failed. Included only when `success` is `false`.
- `speech_detect` (object, optional) — Speech was recognized from the caller. Suppressed when you enable `redact_prompt`.
  - `text` (string, required) — The recognized text.
  - `source` (string, required) — Which recognizer produced the text.
- `barge` (object, optional) — The caller interrupted the agent. The fields differ by session type: a standard session reports `barge_type`, `barge_elapsed_ms`, and `interrupt_count`, while a speech-to-speech session reports `audio_played_ms` and `barge_count`.
  - `barge_type` (enum, optional) — `transparent` when the agent keeps what it already said, `normal` otherwise.
    - Allowed values: `transparent`, `normal`
  - `barge_elapsed_ms` (integer, optional) — How long the agent had been speaking when the caller cut in, in milliseconds.
  - `interrupt_count` (integer, optional) — How many times the caller has interrupted so far.
  - `audio_played_ms` (integer, optional) — How much of the reply had played when the caller cut in, in milliseconds. Speech-to-speech sessions only.
  - `barge_count` (integer, optional) — How many times the caller has interrupted so far. Speech-to-speech sessions only.
- `ai_completion` (object, optional) — The agent finished speaking a reply.
  - `type` (enum, required) — `barged` when the caller interrupted the reply, `normal` when it played to the end.
    - Allowed values: `normal`, `barged`
- `filler` (object, optional) — The agent played a filler phrase while it worked.
  - `text` (string, required) — The phrase that was spoken.
  - `filler_type` (enum, required) — `function` while a tool runs, `thinking` while the model does.
    - Allowed values: `function`, `thinking`
- `attention_timeout` (object, optional, nullable) — The caller went quiet for longer than `attention_timeout`. Sent as `null` on speech-to-speech sessions.
  - `timeout_ms` (integer, required) — The configured timeout, in milliseconds.
- `hold` (object, optional) — The agent was placed on hold, or taken off it. `timeout` and `loop` come with `hold` only.
  - `event` (enum, required) — Which way the hold went.
    - Allowed values: `hold`, `unhold`
  - `timeout` (integer, optional) — How long the hold lasts, in seconds. Absent on `unhold`.
  - `loop` (boolean, optional) — Whether the hold repeats. Absent on `unhold`.
- `function_call` (object, optional) — The agent called one of your functions and the call returned.
  - `function` (string, required) — The name of the function.
  - `duration_ms` (integer, required) — How long the function took, in milliseconds.
  - `native` (boolean, optional) — Whether the function ran inside the platform rather than on your server. Absent on a speech-to-speech shadow call, which reports `shadow` instead.
  - `shadow` (boolean, optional) — Always `true` when present, marking a call the agent made in the background while it kept talking. Speech-to-speech sessions only.
  - `phase` (string, optional) — Where in the session the call happened. Included only for a call made while running the post-prompt.
- `function_loop` (object, optional) — The agent called the same function repeatedly and was stopped. `consecutive` means it was called several times in a row; `repeated` means it was called with the same arguments each time.
  - `function` (string, required) — The name of the function.
  - `type` (enum, required) — Which loop guard tripped.
    - Allowed values: `consecutive`, `repeated`
  - `count` (integer, required) — How many calls triggered the guard.
- `swaig_call` (object, optional) — A completed tool call, the same entry the post-prompt callback later reports in its `swaig_log`.
  - `command_name` (string, required) — The name of the function the agent called.
  - `command_arg` (string, required) — The arguments it passed, as the raw string the model produced.
  - `epoch_time` (integer, required) — When the call was made, as a Unix timestamp in seconds.
  - `native` (boolean, optional) — Always `true` when present, meaning the function ran inside the platform rather than on your server.
  - `active_count` (integer or string, optional) — How many times the function may still be called, or `endless` when it has no limit. Present only on a function you limited.
  - `url` (string, optional) — The URL the function was served from. Present when the call reached your server.
  - `post_data` (object, optional) — The body sent to your server. Present when the call reached it.
  - `post_response` (object, optional) — The response your server returned. Present when the call reached it and got a reply.
  - `delayed_post_response` (object, optional) — A response that arrived after the agent had already moved on. Present only when that happened.
  - `mcp_url` (string, optional) — The MCP server the tool was served from. Present only for an MCP-backed tool.
  - `mcp_tool` (string, optional) — The tool name on that MCP server. Present only for an MCP-backed tool.
  - `mcp_response` (string, optional) — What the MCP server returned. Present only for an MCP-backed tool.
  - `mcp_error` (boolean, optional) — Always `true` when present, meaning the MCP call failed.
- `process_action` (object, optional) — A tool returned a SWAIG action. Carries the action exactly as your endpoint returned it.
- `tool_distill` (object, optional) — A tool result was shortened before the agent read it.
  - `function` (string, required) — The function whose result was shortened.
  - `raw_chars` (integer, required) — Length of the original result, in characters.
  - `distilled_chars` (integer, required) — Length of the shortened result, in characters.
  - `model` (string, required) — The model that did the shortening. `default` when none was configured.
- `webhook` (object, optional) — The webhook definition as you wrote it. Arrives alongside `input`, and alongside `output` and `match` when the call produced a reply, or `error` when the definition was unusable.
- `input` (object, optional) — The body sent to the webhook, or the input an output template was expanded against.
- `output` (object, optional, nullable) — The reply the webhook produced, or the output template that matched. `null` when nothing matched.
- `match` (object, optional, nullable) — The entry that matched. `null` when none did.
- `error_keys` (list of any, optional, nullable) — The `error_keys` declared on the webhook. `null` when it declares none.
- `error` (object, optional) — The webhook could not be evaluated.
  - `error` (string, required) — What went wrong.
  - `errorText` (string, required) — The detail behind it.
- `expression` (object, optional) — The `expressions` entry as you wrote it. Arrives alongside `input` and `output`.
- `webhook_log` (object, optional) — A webhook request completed, with the request and response recorded.
  - `request_url` (string, required) — The URL that was called, after variable expansion.
  - `webhook_response` (object, required) — The response, plus `http_code` and any `parse_error` or `protocol_error` flags.
  - `request_payload` (object, optional) — The body that was sent. Omitted on a request with no body.
- `webhook_reply` (object, optional, nullable) — The final reply the webhook produced, after matching. An array reply is wrapped as `{ "array": [...] }`. `null` when the webhook produced no reply.
- `webhook_fail` (object, optional) — A tool's webhook could not be reached or did not answer usefully, after every retry. Sent whenever a tool call fails, so you can alert on tools breaking mid-call.
  - `call_info` (object, required) — Identifies the call. The same values as the envelope's `call_info`.
    - `call_id` (string, required) — ID of the call.
    - `content_type` (string, required) — The content type of the POST body. Always `text/json`.
    - `content_disposition` (string, required) — How the body is delivered. Always `post_data`.
    - `conversation_type` (string, required) — The conversation type. Always `voice`.
    - `project_id` (string, optional) — Your project ID.
    - `space_id` (string, optional) — Your Space ID.
  - `error` (string, required) — Always `webhook error`.
  - `request_url` (string, required) — The URL that was called.
  - `attempts` (integer, required) — How many attempts were made, including the first.
  - `http_code` (integer, required) — The HTTP status code. `0` when no response was received.
  - `request_payload` (object, optional) — The body that was sent, when there was one.
  - `parse_error` (boolean, optional) — Always `true` when present, meaning the response body was not valid JSON.
  - `raw_response` (string, optional) — The response body as received. Included only when `parse_error` is set.
  - `parsed_response` (object, optional) — The response body parsed as JSON. Omitted when the body could not be parsed, where `parse_error` and `raw_response` carry the detail instead.
  - `protocol_error` (boolean, optional) — Always `true` when present, meaning the request failed before a response was received.
  - `curl_code` (integer, optional) — The transport error code. Included only when `protocol_error` is set.
- `step_change` (object, optional) — The agent moved to a different step.
  - `from_index` (integer, required) — The index of the step it left.
  - `to_step` (string, required) — The step it moved to.
  - `to_index` (integer, required) — The index of the step it moved to.
  - `from_step` (string, optional) — The step it left. Omitted on the first step.
  - `trigger` (enum, optional) — What caused the move. `ai_function` when the agent called `next_step`, `webhook_action` when a tool's response asked for it, `gather_complete` when a gather finished, and `auto_advance` when the step's own advance condition was met.
    - Allowed values: `ai_function`, `webhook_action`, `gather_complete`, `auto_advance`
- `context_change` (object, optional) — The agent moved to a different context.
  - `to_context` (string, required) — The context it moved to.
  - `isolated` (boolean, required) — Whether the new context starts without the previous conversation.
  - `from_context` (string, optional) — The context it left. Omitted on the first context.
  - `trigger` (enum, optional) — What caused the move. `ai_function` when the agent called `change_context`, `webhook_action` when a tool's response asked for it.
    - Allowed values: `ai_function`, `webhook_action`
- `context_switch_data` (object, optional) — The data a context switch was rendered against.
  - `data_root` (object, required) — The variables available to the new context's prompt.
  - `info` (object, required) — The context definition as you wrote it.
- `gather_start` (object, optional) — A `gather` started collecting answers.
  - `context` (string, required) — The context the agent was in. `default` when you define no contexts.
  - `total_questions` (integer, required) — How many questions the gather will ask.
  - `step` (string, optional) — The step the agent was on. Included only when the context defines steps.
  - `step_index` (integer, optional) — The step's index. Included only when the context defines steps.
  - `output_key` (string, optional) — The key the collected answers are stored under. Omitted when none was set.
- `gather_question` (object, optional) — A `gather` asked a question.
  - `context` (string, required) — The context the agent was in. `default` when you define no contexts.
  - `question_index` (integer, required) — The question's position in the gather, starting at 0.
  - `requires_confirm` (boolean, required) — Whether the answer has to be confirmed before the gather moves on.
  - `step` (string, optional) — The step the agent was on. Included only when the context defines steps.
  - `step_index` (integer, optional) — The step's index. Included only when the context defines steps.
  - `key` (string, optional) — The key this question fills. Omitted when none was set.
  - `question_type` (string, optional) — The kind of answer expected. Omitted when unset.
- `gather_answer` (object, optional) — A `gather` accepted an answer.
  - `context` (string, required) — The context the agent was in. `default` when you define no contexts.
  - `question_index` (integer, required) — The question's position in the gather, starting at 0.
  - `attempt` (integer, required) — Which attempt produced the answer, counting from 0.
  - `confirmed` (boolean, required) — Whether the question required the caller to confirm the answer back before it was accepted.
  - `step` (string, optional) — The step the agent was on. Included only when the context defines steps.
  - `step_index` (integer, optional) — The step's index. Included only when the context defines steps.
  - `key` (string, optional) — The key the answer filled. Omitted when none was set.
- `gather_reject` (object, optional) — A `gather` rejected an answer and will ask again.
  - `context` (string, required) — The context the agent was in. `default` when you define no contexts.
  - `question_index` (integer, required) — The question's position in the gather, starting at 0.
  - `attempt` (integer, required) — Which attempt was rejected, counting from 0.
  - `step` (string, optional) — The step the agent was on. Included only when the context defines steps.
  - `step_index` (integer, optional) — The step's index. Included only when the context defines steps.
  - `key` (string, optional) — The key the answer would have filled. Omitted when none was set.
  - `reason` (enum, optional) — Why it was rejected. `missing_answer` when no answer came back, `confirmation_required` when the answer arrived without the confirmation the question demands.
    - Allowed values: `missing_answer`, `confirmation_required`
- `gather_complete` (object, optional) — A `gather` finished.
  - `context` (string, required) — The context the agent was in. `default` when you define no contexts.
  - `answered` (integer, required) — How many questions were answered.
  - `step` (string, optional) — The step the agent was on. Included only when the context defines steps.
  - `step_index` (integer, optional) — The step's index. Included only when the context defines steps.
  - `output_key` (string, optional) — The key the collected answers were stored under. Omitted when none was set.
  - `completion_action` (string, optional) — What the gather did on completion. Omitted when nothing recorded it.
- `conversation_add` (object, optional) — A message was added to the conversation, one per turn. Sent only at `debug_webhook_level` `2` and above. This is the same message that later appears in the post-prompt callback's `call_log`.
  - `role` (string, required) — Who produced the message: `system`, `user`, `assistant`, or `tool`.
  - `content` (string, required) — The message text. Redacted when you enable `redact_prompt`.
  - `lang` (string, optional) — The language the message was in. Omitted on tool messages.
  - `tokens` (integer, optional) — Tokens the message consumed. Omitted on tool messages.
  - `timestamp` (long, optional) — When the message was added, as a Unix timestamp in microseconds.
  - `tool_call_id` (string, optional) — Links a tool result back to the call that produced it. Present on tool messages.
  - `metadata` (object, optional) — Per-turn detail. On a caller turn this carries `confidence`, `content_type`, and the speaking-to-final timings. Omitted on turns that have none.
- `llm_request` (object, optional) — The agent is about to call the model. Sent only at `debug_webhook_level` `2` and above.
  - `model` (string, required) — The model being called.
  - `prompt_tokens` (integer, required) — Tokens in the prompt.
  - `conversation_tokens` (integer, required) — Tokens in the conversation so far.
- `llm_response` (object, optional) — The model answered. Sent only at `debug_webhook_level` `2` and above.
  - `model` (string, required) — The model that was called.
  - `output_tokens` (integer, required) — Tokens in the answer.
  - `duration_ms` (integer, required) — How long the call took, in milliseconds.
  - `success` (boolean, required) — Whether the model returned anything.
  - `error` (string, optional) — A description of the failure. Included only when the call failed.
- `llm_error` (object, optional) — A model call failed or had to be retried. Read `event` for which: `token_exhaustion` and `llm_fatal` end the session, `llm_max_retries` gives up after repeated failures, and `llm_retry`, `reasoning_only_retry`, `empty_response_nudge_retry`, and `empty_response_effort_bump_retry` recover silently.
  - `event` (enum, required) — Which failure this is.
    - Allowed values: `token_exhaustion`, `llm_fatal`, `llm_max_retries`, `reasoning_only_retry`, `empty_response_nudge_retry`, `empty_response_effort_bump_retry`, `llm_retry`
  - `model` (string, optional) — The model that was called. Omitted on `token_exhaustion`.
  - `token_count` (integer, optional) — Tokens in the conversation. Included only on `token_exhaustion`.
  - `limit` (integer, optional) — The token ceiling that was hit. Included only on `token_exhaustion`.
  - `errors` (integer, optional) — How many failures have accumulated. Included only on `llm_max_retries`.
  - `reasoning_effort` (string, optional) — The effort level being retried at. Included only on `empty_response_effort_bump_retry`.
- `consolidation` (object, optional) — The conversation passed its token ceiling and was summarized to make room.
  - `event` (string, required) — Always `consolidation`.
  - `token_count` (integer, required) — Tokens in the conversation when it tripped.
  - `limit` (integer, required) — The ceiling that was hit.
- `summarize_start` (object, optional) — The post-prompt summary is about to be generated.
  - `mode` (string, required) — How the summary is being produced.
  - `model` (string, required) — The model producing it. `default` when none was configured.
- `post_prompt` (object, optional) — The post-prompt report was delivered.
  - `url` (string, required) — The URL the report was sent to.
- `text_normalize` (object, optional) — Text was rewritten between spoken and written form, for recognition or speech.
  - `direction` (enum, required) — `tn` rewrites text for speaking, `itn` rewrites recognized speech for reading.
    - Allowed values: `tn`, `itn`
  - `language` (string, required) — The language the rewrite ran in.
  - `original` (string, required) — The text before the rewrite.
  - `normalized` (string, required) — The text after it.
- `voice_error` (object, optional) — The configured voice could not be used and the agent fell back to another.
  - `event` (enum, required) — `voice_config_error` when the voice was invalid, `voice_runtime_error` when it failed mid-call.
    - Allowed values: `voice_config_error`, `voice_runtime_error`
  - `engine` (string, required) — The engine that failed.
  - `voice` (string, required) — The voice that failed.
  - `fallback_engine` (string, required) — The engine used instead.
  - `fallback_voice` (string, required) — The voice used instead.
- `warning` (object, optional) — Something about the configuration is likely to cause trouble.
  - `event` (string, required) — Which warning this is.
  - `tokens` (integer, required) — Tokens in the prompt that triggered it.
- `oart_user_transcript` (object, optional) — The caller's speech was transcribed. Speech-to-speech sessions only.
  - `text` (string, required) — The transcribed text.
- `oart_assistant_transcript` (object, optional) — The agent's speech was transcribed. Speech-to-speech sessions only.
  - `text` (string, required) — The transcribed text.
- `oart_response_done` (object, optional) — The agent finished a reply, with its timings. Speech-to-speech sessions only.
  - `latency` (integer, required) — Time from the end of the caller's turn to the start of the reply, in milliseconds.
  - `utterance_latency` (integer, required) — Time to the first word of the reply, in milliseconds.
  - `audio_latency` (integer, required) — Time to the first audio of the reply, in milliseconds.
  - `acoustic_latency` (integer, required) — Time to the first sound leaving the platform, in milliseconds.
  - `status` (string, optional) — How the reply finished. Omitted when nothing recorded it.
- `inner_dialog` (object, optional) — The agent's private reasoning, when you enable `enable_inner_dialog`. Speech-to-speech sessions only.
  - `text` (string, required) — The reasoning text. The caller never hears this.