ws://<host>:<VOICE_PORT>/audio
Default: ws://localhost:3000/audio
Audio Format
All audio data is transmitted as raw PCM in binary WebSocket frames.
Both client-to-server (microphone audio) and server-to-client (TTS audio) use the same format.
Connection Lifecycle
1
Connect
Client opens a WebSocket connection to
ws://<host>:<VOICE_PORT>/audio.2
Session Ack
Server immediately sends a
session_ack message with the assigned sessionId and audio configuration.3
Session Start (optional)
Client sends
session_start with an optional deviceId to identify the hardware.4
Audio Streaming
Client sends binary frames containing raw PCM audio from the microphone. Server processes through the voice pipeline (VAD, STT, LLM, TTS).
5
TTS Playback
Server sends
tts_start, followed by binary PCM audio frames, followed by tts_end.6
Session End (optional)
Client sends
session_end to signal end of conversation.7
Disconnect
Either side closes the WebSocket connection.
Client to Server Messages
Binary Frames: Audio Data
Raw PCM audio from the client microphone. Must match the audio format specification (Int16, 16kHz, mono, little-endian). Send audio in chunks as they become available from the microphone. There is no required chunk size, but typical sizes are 320 bytes (10ms) to 3200 bytes (100ms).Text Frames: Control Messages
All control messages are JSON objects with atype field.
session_start
session_start
Sent after connection to identify the device and begin a voice session.
session_end
session_end
Signal the end of a voice session. The WebSocket connection remains open.
config
config
Update runtime configuration for this connection.
status
status
Request connection status from the server. Server responds with a
status control message.Server to Client Messages
Binary Frames: TTS Audio Data
Raw PCM audio synthesized by the TTS engine. Same format as client audio: Int16, 16kHz, mono, little-endian. Sent betweentts_start and tts_end control messages.
Text Frames: Control Messages
session_ack
session_ack
Sent immediately after connection to confirm session assignment and audio configuration.
tts_start
tts_start
Indicates that TTS audio frames will follow. The client should prepare to play audio.
tts_end
tts_end
Indicates that all TTS audio frames for the current utterance have been sent.
error
error
Sent when an error occurs during processing.
transcript
transcript
Sent when speech has been transcribed (STT result) or when the assistant produces a text response. Includes the transcript text, the role that produced it, and optional word-level timestamps.
status
status
Response to a client
status request. Contains connection metrics.Keepalive and Timeout
The server sends WebSocketping frames at a configurable interval (default: 30 seconds). Clients must respond with pong frames (this is handled automatically by most WebSocket libraries).
If a client does not respond to a ping with a pong before the next ping cycle, the server considers the client unresponsive and terminates the connection.
Connection Limits
Error Handling
Connection Rejection
Runtime Errors
Errors during audio processing (STT failure, LLM timeout, TTS error) are reported viaerror control messages. The WebSocket connection remains open so the client can retry.
Reconnection
1
Initial Wait
Wait 1 second after first disconnection.
2
Backoff
Double the wait time on each subsequent attempt (2s, 4s, 8s…).
3
Cap
Cap the maximum wait at 30 seconds.
4
Reset
Reset the backoff timer after a successful connection.
Example: Browser Client
Example: ESP32 Client
For ESP32 firmware using the XIAO ESP32-S3 Sense, see the firmware repository. The ESP32 streams I2S microphone data (PDM, pins 42/41) as raw PCM over WebSocket and plays back TTS audio through an I2S DAC.Key considerations for ESP32:
- Use binary WebSocket frames for audio data.
- Buffer at least 100ms of audio before sending to reduce frame overhead.
- Handle
ping/pongkeepalive (most ESP32 WebSocket libraries handle this automatically). - Implement reconnection with backoff for Wi-Fi instability.