Skip to main content
This is the stream behind Live Monitoring in the dashboard. For a call that has already ended, use Get Call instead: it returns the final transcript with word timestamps and, when PII scrubbing is on, the scrubbed version.

Overview

The monitor call WebSocket streams a live call’s transcript to your server while the call is in progress. Connect with your API key to receive every agent and user turn, tool call, and node transition as JSON events, starting with a snapshot of the conversation so far and ending when the call ends. Your server opens this connection and Retell sends events on it. Your server doesn’t send anything back. Use it when you need the conversation while it’s still happening:
  • Show live transcripts in your own tools. Build a supervisor console, embed the transcript in your CRM, or mirror the call in an internal dashboard.
  • React mid-call. Page a human when the flow reaches an escalation node, alert on a failed tool call, or flag a keyword before the call ends.
  • Audit in real time. Watch sensitive conversations as they happen instead of only in review.
For example, a dental clinic streams every appointment call into its own operations console. When the agent reaches the “Escalate to staff” node, the clinic’s server posts the last few turns to the front-desk channel, and a receptionist picks up the call from the dashboard with Take Over.

Endpoint

WebSocket endpoint: wss://api.retellai.com/v2/monitor-call/{call_id}

Path parameters

string
required
Id of the call to monitor. The call must belong to your workspace and be in progress (call_status is ongoing).

Headers

string
required
Bearer YOUR_RETELL_API_KEY, the same as for REST requests. A key with restricted permissions needs Call → Edit. Keys without restrictions work as is. See Manage API keys.
Connect from a server, not a browser. Browsers can’t set headers on a WebSocket handshake, so a browser client would have to expose your API key. To show the live transcript in a web page, relay the events through your own backend.

Connection limits

  • The call must be ongoing. A registered call that hasn’t connected yet, or a call that has ended, is rejected with close code 4004. Connect when you receive the call_started webhook, or once Get Call reports ongoing.
  • Up to 5 connections per call (as of September 2026). Dashboard viewers count toward the same limit. A sixth connection is rejected with close code 4008 and the reason max watchers reached.

Protocol

Retell sends events to your server over this WebSocket following the protocol below. All messages are text frames whose data is a stringified JSON object. Check the type field to tell events apart. The stream carries text only. Transcript items have the text and a start time, not per-word timing, so fetch the call with Get Call after it ends for word timestamps. During an agentic warm transfer, the transfer agent’s conversation with the transfer target isn’t streamed; it appears in the Get Call transcript as transfer_target utterances after the call. The text is always the raw transcript: PII scrubbing runs after a call ends, so no scrubbed version exists mid-call. Treat the stream as sensitive data. To hear live audio, use Live Listen in the dashboard.

Event flow

Once Retell validates your key and the call, it admits the connection and sends one transcript snapshot event with everything said so far, so a connection that joins mid-call starts complete. As the call goes on, each change arrives as a transcript updated event: a new user or agent turn, more text on the current turn, a tool call and its result, a node transition, a keypad press, an SMS, or injected context. When the call ends, Retell sends a call ended event and closes the connection with code 1000 and the reason call_ended. Every transcript item has a stable id. When an id arrives again, the new item replaces the old one: as a speaker keeps talking, their current turn is re-sent with the full text so far. Keep items in a map keyed by id and sort by time_sec for display, and you have the live transcript. The snapshot can arrive after the first updates, so apply the same replace-by-id logic to both. If your connection drops while the call is still ongoing, reconnect. The new connection gets a fresh snapshot, and replace-by-id handles any overlap. If the call’s server disappears without sending call_ended (for example, an infrastructure failure), Retell closes the connection within about a minute with code 1000 and the reason call_ended, possibly without a call ended event first.

Retell -> your server event spec

Retell sends three kinds of events to your server in this WebSocket. To differentiate between them, check the type field:
  • transcript_snapshot: sent once after the connection is admitted, with the whole transcript so far
  • transcript_updated: sent whenever the transcript changes
  • call_ended: sent once when the call ends, right before Retell closes the connection

Transcript snapshot event

Sent once, shortly after the connection is admitted. Retell requests the snapshot from the call’s server after your connection opens, so it can arrive after the first transcript updated events.
enum<string>
required
Differentiate what this event is.Available options: transcript_snapshot
object[]
required
Every transcript item in the call so far, sorted by time_sec. Empty if nothing has been said yet.
object[]
required
Calls made by the agent’s pre-session tools before the conversation started, as tool_call_invocation and tool_call_result items. Empty when the agent has no pre-session tools.

Transcript updated event

Sent whenever the transcript changes. Each event carries one changed item. The exception is a pre-session update, where transcripts is empty and pre_session_transcripts carries the full pre-session list.
enum<string>
required
Differentiate what this event is.Available options: transcript_updated
object[]
required
The transcript item that changed, as a one-element array. An item whose id you have already seen replaces the earlier version. Empty when the event only carries pre_session_transcripts.
object[]
Present only when pre-session tool results arrive after you connect. Contains every pre-session item so far, in the same shape as the snapshot.

Call ended event

The last message before Retell closes the connection with code 1000.
enum<string>
required
Differentiate what this event is.Available options: call_ended
integer
When the call ended, in milliseconds since the Unix epoch.
string
Why the call ended, such as user_hangup or agent_hangup. Same values as disconnection_reason in the Get Call response.

Transcript item spec

Each item in transcripts and pre_session_transcripts carries the fields below, plus the fields for its role. The id is the role followed by a per-role counter, such as agent_2 or tool_call_invocation_0.
string
required
Stable id for this item. A later item with the same id replaces this one.
number
required
When the item started, in seconds from the start of the call. For user and agent items this is the start of the first word, or 0 before any word timing exists. Sort by this field for display and keep arrival order for ties.
enum<string>
required
What kind of item this is.Available options: user, agent, tool_call_invocation, tool_call_result, node_transition, dtmf, sms, injected

User and agent items

A spoken turn.
string
required
The text of the turn so far. It grows while the speaker continues, and each change re-sends the item. When the caller’s speech couldn’t be recognized, content is (unintelligible audio).

Tool call invocation item

The agent called a tool. Match it to its result with tool_call_id.
string
required
Unique id of the tool call.
string
required
Name of the tool.
string
required
Arguments passed to the tool, as a stringified JSON object.
enum<string>
Kind of tool.Available options: custom, code, mcp, integration_app, end_call, transfer_call, bridge_transfer, cancel_transfer, agent_swap, press_digit, send_sms, extract_dynamic_variable, adjust_voice_speed, book_appointment_cal, check_availability_cal

Tool call result item

The tool the agent called returned.
string
required
Id of the invocation this result belongs to.
string
required
What the tool returned, often a stringified JSON object.
boolean
Whether the tool call succeeded. Absent when the outcome wasn’t recorded, which doesn’t mean it failed.

Node transition item

A conversation flow agent moved to another node.
string
required
Id of the node the agent left.
string
required
Name of the node the agent left.
string
required
Id of the node the agent entered.
string
required
Name of the node the agent entered.
enum<string>
required
How the node was reached: normal for a regular edge, global for a global node, global_go_back when returning from a global node, or interrupt_go_back when returning after a user interruption.Available options: normal, global, global_go_back, interrupt_go_back

DTMF item

The caller pressed a key on their phone keypad.
string
required
The key pressed: a single character such as 1, *, or #.

SMS item

An SMS the caller sent during the call, for example while the agent was leaving a voicemail. Not part of the spoken conversation.
string
required
Text of the message.
object[]
MMS attachments. Display only.

Injected item

Context your server added mid-call with Update Live Call. Not spoken by either party.
string
required
The injected text.

Close codes

Retell closes the connection with a standard WebSocket close frame. The reason text says why.

Sample events

Retell -> your server sample events

Transcript item sample events

Each of these appears inside the transcripts array of a snapshot or update. Pre-session tool calls use the same shapes inside pre_session_transcripts.

FAQ

No. The stream is transcript only. Live audio is available in the dashboard through Live Listen, and the recording is available from Get Call after the call ends.
The call hasn’t connected yet. Monitoring requires a call_status of ongoing, and a call stays registered until the callee answers or the web client joins. Wait for the call_started webhook, or poll Get Call, then connect.
That’s how updates work. A user or agent turn is re-sent with more text as the speaker continues, and the snapshot can overlap with updates that arrived first. Replace items by id.
No. Retell sends every event and closes the connection when the call ends. There is no config, ping, or acknowledgement to send back, unlike the LLM WebSocket.
Phone calls and web calls, yes. Chats aren’t calls and can’t be monitored with this WebSocket.
Only through your own backend. Browsers can’t set the Authorization header on a WebSocket handshake, and your API key must stay server side. Relay the events from your server to the browser.