Voice WebSocket Protocol
Stream real-time voice call events over a persistent WebSocket connection. Use this protocol for live dashboards, call monitoring, real-time transcription displays, and custom call control interfaces.Connection Setup
Endpoint
Authentication
Include your API key as a query parameter or in the first message after connection:auth message after connecting:
auth.success or auth.error message:
SDK Connection
The SDKs handle connection, authentication, and reconnection automatically.Message Format
All messages follow a consistent envelope format:| Field | Type | Description |
|---|---|---|
type | string | Message type identifier |
timestamp | string | ISO 8601 timestamp of the event |
data | object | Event-specific payload |
Message Types
call.started
Emitted when an outbound or inbound call is connected.| Field | Type | Description |
|---|---|---|
callId | string | Unique call identifier |
agentId | string | Agent handling the call |
direction | string | "outbound" or "inbound" |
from | string | Caller phone number (E.164) |
to | string | Callee phone number (E.164) |
voiceId | string | Voice model used for the call |
recordingEnabled | boolean | Whether recording is active |
call.ringing
Emitted when the outbound call is ringing on the recipient’s end.call.answered
Emitted when the recipient picks up.call.transcription
Emitted in real-time as speech is transcribed. Segments may be partial (streaming) or final.| Field | Type | Description |
|---|---|---|
segmentId | string | Unique segment identifier |
speaker | string | "agent" or "caller" |
text | string | Transcribed text |
isFinal | boolean | false for partial, true for finalized |
confidence | number | Transcription confidence (0.0 - 1.0) |
startTime | number | Seconds from call start |
endTime | number | Seconds from call start |
language | string | Detected language code |
call.agent_response
Emitted when the agent generates a response that will be spoken.call.dtmf
Emitted when the caller presses a key on their phone keypad (DTMF tone).| Field | Type | Description |
|---|---|---|
digit | string | Key pressed: "0"-"9", "*", "#" |
durationMs | number | How long the key was held (milliseconds) |
call.hold
Emitted when the call is placed on or taken off hold.| Field | Type | Description |
|---|---|---|
status | string | "on_hold" or "resumed" |
call.transfer
Emitted when the call is transferred to another number or agent.call.sentiment
Emitted periodically with rolling sentiment analysis.| Field | Type | Description |
|---|---|---|
current | string | "positive", "neutral", or "negative" |
score | number | Sentiment score (-1.0 to 1.0) |
trend | string | "improving", "stable", or "declining" |
call.ended
Emitted when the call terminates for any reason.| Field | Type | Description |
|---|---|---|
reason | string | "completed", "caller_hangup", "agent_hangup", "no_answer", "busy", "failed", "timeout" |
durationSeconds | number | Total call duration in seconds |
recordingUrl | string | Signed URL to the recording (if enabled) |
transcriptAvailable | boolean | Whether the full transcript is ready |
summary | string | AI-generated call summary |
call.error
Emitted when an error occurs during the call.Subscribing to Specific Calls
Filter events to a specific call or agent by sending asubscribe message:
Heartbeat / Ping-Pong
The server sends aping message every 30 seconds. The client must respond with a pong within 10 seconds or the connection will be closed.
ping.
Error Handling
Connection Errors
| Code | Reason | Action |
|---|---|---|
4001 | Invalid API key | Check your API key and reconnect |
4002 | Rate limit exceeded | Back off and retry after the Retry-After header |
4003 | Connection limit reached | Close unused connections before opening new ones |
4008 | Ping timeout | Client did not respond to ping in time; reconnect |
4500 | Internal server error | Retry with exponential backoff |
Reconnection Strategy
Use exponential backoff with jitter for automatic reconnection:- First retry: 1 second
- Second retry: 2 seconds
- Third retry: 4 seconds
- Max backoff: 30 seconds
- Add random jitter of 0-1 seconds to each delay
Next Steps
- Quickstart: Voice Calls — Make your first AI-powered phone call
- Voice Catalog — Browse available voice models
- Call Intelligence — Recording, transcription, and scoring
- Webhooks — HTTP-based event delivery as an alternative to WebSocket
