> For complete lifecycle-event payload schemas and examples, use the canonical overview: Session /api/sessions; Room lifecycle, participants, and room playback /api/rooms; Session playback /api/playback; Recording /api/recording; DTMF /api/keypad-input; Messages /api/messages; WebSocket Session /api/web-socket. Use /api/event-delivery for transport behavior. Endpoint pages name relevant events, but these overviews are the canonical references. # WebSocket overview > Complete WebSocket Session connection and lifecycle-event reference. A WebSocket Session is a media-only participant backed by a connection to your WebSocket server. Create one with [`POST /v1/sessions:connectWebsocket`](/api/sessions/connect-websocket) when your application needs to exchange live audio without creating a phone call. ## When to use Use WebSocket to connect a real-time voice application, such as a voice agent or live transcription service, to a conversation. ## Use the Session in a Room Add the WebSocket Session and one or more phone Sessions to a [Room](/api/rooms) to build a bidirectional voice agent. Your server receives audio from the WebSocket Session and sends audio back through the same connection. The Room connects that media to the other participants. ## Connection lifecycle The create request returns a Session in the `connecting` state while the platform opens the WebSocket connection. The Session becomes `answered` after your server accepts the connection. If the connection fails or closes, the WebSocket Session ends. Follow the lifecycle events on this page to observe connection success, connection failure, disconnection, and completion of buffered audio playback. Follow [Session lifecycle events](/api/sessions#lifecycle-events) for the complete WebSocket Session lifecycle. ## Audio format The Session exchanges raw mono audio in binary WebSocket messages without a WAV header. The required `media_format` object configures each direction from the Session's perspective: * `from_session` describes audio that the platform sends from the Session to your WebSocket server. * `to_session` describes audio that your WebSocket server sends to the Session. Each direction independently accepts signed 16-bit little-endian PCM at a supported multiple of 8 kHz, or G.711 mu-law at 8 kHz. The two directions can use different formats. See [WebSocket audio formats](/formats#websocket-audio) for the supported matrix and [`POST /v1/sessions:connectWebsocket`](/api/sessions/connect-websocket) for the complete request schema. The platform exchanges raw audio only. It does not implement Twilio Media Streams JSON envelopes, base64 payloads, or control messages. ## Lifecycle events These events report the WebSocket connection owned by a `type: "websocket"` Session created through [`POST /v1/sessions:connectWebsocket`](/api/sessions/connect-websocket). The wire event names use the `websocket.*` namespace. > **Info** > > All webhook deliveries are signed. See [Verifying signatures](/api/event-delivery#signature-verification) before processing an event. Every event contains these fields. `operation_uuid` is optional; all other fields are required. | Field | Type | Description | | ---------------- | ------ | ---------------------------------------------------------------------------------- | | `aud` | string | Application UUID that identifies the intended recipient. | | `event` | string | Exact event name documented in the corresponding section. | | `session_uuid` | string | WebSocket Session identifier. | | `operation_uuid` | string | Originating WebSocket operation identifier. Present when correlation is available. | | `timestamp` | string | RFC 3339 UTC event time with a `Z` suffix. | ## websocket.connected Fires after your WebSocket server accepts the connection and the connection is ready to exchange audio. The WebSocket Session then advances from `connecting` to `answered` without emitting `session.answered`. This event confirms connection readiness. It does not confirm that audio has been sent, received, or heard by a Room participant. If DNS resolution, TCP or TLS connection establishment, or the WebSocket handshake fails during setup, the Session emits `websocket.failed` without a preceding `websocket.connected` for that connection attempt. ```json { "aud": "app_3f9c0b2a-7d41-4e8b-9f12-2a6c5d0e7b34", "event": "websocket.connected", "session_uuid": "00000000-0000-4000-8000-000000000101", "operation_uuid": "550e8400-e29b-41d4-a716-446655440000", "timestamp": "2026-08-23T08:53:20.000Z" } ``` ## websocket.disconnected Fires when an established connection closes unexpectedly or the WebSocket server initiates the close. The event also contains: | Field | Type | Description | | -------- | ------- | ----------------------------------------------------------------- | | `code` | integer | WebSocket close code, or `0` when unavailable. | | `reason` | string | Human-readable close reason, or an empty string when unavailable. | ```json { "aud": "app_3f9c0b2a-7d41-4e8b-9f12-2a6c5d0e7b34", "event": "websocket.disconnected", "session_uuid": "00000000-0000-4000-8000-000000000101", "operation_uuid": "550e8400-e29b-41d4-a716-446655440000", "code": 1000, "reason": "bye", "timestamp": "2026-08-23T08:54:20.000Z" } ``` The WebSocket Session ends after this event, and a [`session.ended`](/api/sessions#sessionended) event follows. ## websocket.failed Fires when the connection cannot become usable. The event also contains: | Field | Type | Description | | ------------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | | `error` | string | Sanitized category: `handshake_failed` or `connection_failed`. | | `http_status` | integer | WebSocket handshake response status, or `0` when no response was available. | | `reason` | string | Stable reason: `session_codec_unsupported`, `destination_unreachable`, `tls_failed`, `handshake_rejected`, or `connection_precondition_failed`. | ```json { "aud": "app_3f9c0b2a-7d41-4e8b-9f12-2a6c5d0e7b34", "event": "websocket.failed", "session_uuid": "00000000-0000-4000-8000-000000000101", "operation_uuid": "550e8400-e29b-41d4-a716-446655440000", "error": "handshake_failed", "http_status": 403, "reason": "handshake_rejected", "timestamp": "2026-08-23T08:53:20.000Z" } ``` The WebSocket Session ends after this event, and a [`session.ended`](/api/sessions#sessionended) event follows. ## websocket.audio_playback_completed Fires when the platform reports that all buffered audio received from the WebSocket server has played and the buffer is idle. The event also contains: | Field | Type | Description | | ----------- | ------- | ------------------------------------------------------------------------- | | `played_ms` | integer | Milliseconds of server audio reported as played, or `0` when unavailable. | ```json { "aud": "app_3f9c0b2a-7d41-4e8b-9f12-2a6c5d0e7b34", "event": "websocket.audio_playback_completed", "session_uuid": "00000000-0000-4000-8000-000000000101", "operation_uuid": "550e8400-e29b-41d4-a716-446655440000", "played_ms": 1840, "timestamp": "2026-08-23T08:54:22.000Z" } ``` Treat this as a lifecycle signal from the platform. A successful WebSocket connection or this event alone does not prove that another participant received non-silent audio. > Build reliable calling experiences with Vorbal APIs for calls, media, messaging, and webhooks. ## API Docs - WebSocket [Create a WebSocket session](https://docs.vorbal.dev/api/web-socket/connect-websocket.md) ## OpenAPI Specification The raw OpenAPI 3.1 specification for this API is available at: - [OpenAPI JSON](https://docs.vorbal.dev/openapi.json) - [OpenAPI YAML](https://docs.vorbal.dev/openapi.yaml)