> For the complete documentation index, see [llms.txt](https://docs.amigo.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.amigo.ai/developer-guide/platform-api/conversations/observer-events.md).

# Observer Events

The observer WebSocket delivers real-time events during a voice session - transcripts, state transitions, tool calls, emotion analysis, latency timing, and call control. Each event has a `type` field that identifies it, and clients can use this field as a discriminator to handle events with type safety. This page is the authoritative catalog of observer events, grouped by category below. For workspace-level events delivered over SSE (calls, text sessions, surfaces, email delivery), see [SSE Events](/developer-guide/platform-api/conversations/sse-events.md).

## Event Types

### Session Lifecycle

| Event Type      | Description                      | Key Fields                                                                                           |
| --------------- | -------------------------------- | ---------------------------------------------------------------------------------------------------- |
| `session_info`  | Session metadata sent on connect | `call_sid`, `service_id`, `workspace_id`, `current_state`, `direction`, `duration_seconds`           |
| `session_start` | Marks the beginning of a session | `call_sid`, `session_id`, `service_id`, `workspace_id`, `initial_state`, `mode`, `trace_id`          |
| `session_end`   | Marks the end of a session       | `call_sid`, `session_id`, `duration_s`, `turns`, `completion_reason`, `final_state`, `has_recording` |

### Runtime Lifecycle

| Event Type        | Description                                                    | Key Fields                               |
| ----------------- | -------------------------------------------------------------- | ---------------------------------------- |
| `actor_allocated` | The call was assigned an isolated voice runtime                | `gameserver`, `node`, `alloc_latency_ms` |
| `media_attached`  | A caller, agent, or operator media leg attached to the runtime | `leg`                                    |
| `actor_shutdown`  | The isolated voice runtime was released                        | `reason`, `lifetime_s`                   |

### Transcripts

| Event Type               | Description                    | Key Fields                                                                                                 |
| ------------------------ | ------------------------------ | ---------------------------------------------------------------------------------------------------------- |
| `user_transcript`        | Caller speech, finalized       | `transcript`, `state`, `speaker_id`, `speaker_role`, `stt_confidence`, `eot_confidence`, `is_barge_in`     |
| `agent_transcript`       | Agent speech, finalized        | `transcript`, `action`, `interrupted`, `filler_type` (optional), `speaker_id`, `speaker_role`, `streaming` |
| `agent_transcript_delta` | Incremental agent speech token | `delta`                                                                                                    |

The `filler_type` field on agent transcripts is one of: `empathy`, `receipt`, `working`.

### State and Navigation

| Event Type         | Description                              | Key Fields                                                      |
| ------------------ | ---------------------------------------- | --------------------------------------------------------------- |
| `state_transition` | Agent moved between context graph states | `previous_state`, `next_state`, `transition_type`, `annotation` |

### Tools

| Event Type            | Description          | Key Fields                                                                                         |
| --------------------- | -------------------- | -------------------------------------------------------------------------------------------------- |
| `tool_call_started`   | A tool call began    | `tool_name`, `call_id`, `input`, `parent_call_id`, `integration_name`, `endpoint_name`, `protocol` |
| `tool_call_completed` | A tool call finished | `tool_name`, `call_id`, `output` (truncated), `succeeded`, `duration_ms`, `error_message`          |

### Latency and Timing

| Event Type   | Description                         | Key Fields                                                                                                                                 |
| ------------ | ----------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
| `latency`    | End-to-end latency breakdown        | `e2e_ttfb_ms`, `engine_ms`, `nav_ms`, `render_ms`, `audio_ttfb_ms`, `continuation`, `is_greeting`                                          |
| `nav_timing` | Navigation and render timing detail | `nav_ms`, `render_ms`, `total_ms`, `input_tokens`, `output_tokens`, `model`, `state`, `retry_attempts`, `used_fallback`, `selected_action` |

### Emotion and Empathy

| Event Type           | Description                       | Key Fields                                                                                |
| -------------------- | --------------------------------- | ----------------------------------------------------------------------------------------- |
| `emotion`            | Caller emotion analysis           | `dominant`, `valence`, `arousal`, `trend`, `coherence`, `scores`, `speaker` (acoustics)   |
| `compound_emotion`   | Blended emotion scores for a turn | `compounds` (list of name/score pairs), `turn_index`                                      |
| `empathy_classified` | Empathy tier selection            | `tier`, `tier_name`, `should_pause`, `suppress_filler`, `filler_type`, `empathy_baseline` |

### Barge-In and Participants

| Event Type           | Description                          | Key Fields                                               |
| -------------------- | ------------------------------------ | -------------------------------------------------------- |
| `barge_in`           | Caller interrupted the agent         | `interrupted_text`, `discarded_texts`, `total_barge_ins` |
| `participant_joined` | A participant entered the conference | `participant_id`, `participant_role`, `conference_sid`   |
| `participant_left`   | A participant left the conference    | `participant_id`, `participant_role`, `conference_sid`   |

### Call Control

| Event Type              | Description                                                 | Key Fields                                          |
| ----------------------- | ----------------------------------------------------------- | --------------------------------------------------- |
| `forward_call_resolved` | Call forwarding completed                                   | `target_number`, `location_name`, `result`, `error` |
| `speaker_muted`         | Speaker mute state changed                                  | `muted`                                             |
| `injected_event`        | An external event or guidance was injected into the session | `message`, `sender`, `event_type`                   |

### Voice Context

| Event Type              | Description              | Key Fields                                                                                           |
| ----------------------- | ------------------------ | ---------------------------------------------------------------------------------------------------- |
| `voice_context_applied` | Voice parameters updated | `tts_emotion`, `tts_speed`, `tts_volume`, `filler_enabled`, `emotion_detection_enabled`, `reasoning` |

### Keepalive

The stream also emits a periodic `ping` event with an empty payload to keep the connection alive. Clients can safely ignore it.

## Common Fields

Every event frame on the observer stream is a JSON object with this envelope:

| Field       | Type      | Description                                                                |
| ----------- | --------- | -------------------------------------------------------------------------- |
| `type`      | `string`  | Event type discriminator                                                   |
| `data`      | `object`  | The event-specific fields listed in the tables above                       |
| `timestamp` | `number`  | Unix epoch seconds                                                         |
| `seq`       | `integer` | Monotonic per-call sequence number, used for ordering and late-join replay |

The call itself is identified by the WebSocket URL path, not by an envelope field. `call_sid` appears inside the `data` payload of session lifecycle events only, and the `call_id` field on `tool_call_started` / `tool_call_completed` is the tool-call invocation ID, not the call identifier. The connect-time `session_info` snapshot and the `ping` keepalive omit `timestamp` and `seq`.

## Participant Roles

The `participant_joined` and `participant_left` events use a `participant_role` field with these values:

| Role       | Description                                |
| ---------- | ------------------------------------------ |
| `caller`   | The end user on the call                   |
| `agent`    | The AI voice agent                         |
| `operator` | A human operator who joined via escalation |

## Empathy Tiers

The `empathy_classified` event includes a `tier_name` field with these values:

| Tier Name      | Description                            |
| -------------- | -------------------------------------- |
| `FUNCTIONAL`   | Standard conversational tone           |
| `LIGHT_TOUCH`  | Brief acknowledgment of caller emotion |
| `FULL_EMPATHY` | Extended empathetic response           |
| `HOLD_SPACE`   | Pause and hold space for the caller    |

## Emotion Trends

The `emotion` event includes a `trend` field indicating the direction of the caller's emotional state:

| Trend           | Description                                  |
| --------------- | -------------------------------------------- |
| `improving`     | Caller emotion is trending more positive     |
| `stable`        | Caller emotion is not changing significantly |
| `deteriorating` | Caller emotion is trending more negative     |

## PHI Annotations

Fields that may contain protected health information are annotated in the schema with `x-phi: true`. Consumers that persist or log observer payloads can use this annotation to apply redaction or access controls:

| Event                    | Field                                              |
| ------------------------ | -------------------------------------------------- |
| `user_transcript`        | `transcript`                                       |
| `agent_transcript`       | `transcript`                                       |
| `agent_transcript_delta` | `delta`                                            |
| `tool_call_started`      | `input`                                            |
| `tool_call_completed`    | `output`                                           |
| `forward_call_resolved`  | `target_number`                                    |
| `session_info`           | `caller_id`                                        |
| `barge_in`               | `interrupted_text`, `discarded_texts`              |
| `emotion`                | `verified_speaker_id`                              |
| `participant_joined`     | `participant_name`, `display_name`, `phone_number` |
| `participant_left`       | `display_name`, `phone_number`                     |

## Handling Unknown Events

New event types may be added in future releases. Clients should ignore event types they do not recognize rather than treating them as errors. This ensures forward compatibility as the observer stream is extended.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.amigo.ai/developer-guide/platform-api/conversations/observer-events.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
