Realtime Audio WebSocket API¶
Use WS /v1/realtime to stream PCM audio into a compatible omni model and receive incremental transcription and synthesized response audio. This is a turn-based streaming API: it starts one generation over an audio stream and finishes after the client closes that input stream.
For a model that listens while it is already speaking, use the Full-Duplex API instead.
Quick Start¶
Start a compatible model. The currently documented example uses Qwen3-Omni:
Run the provided client with a mono, 16-bit PCM, 16 kHz WAV file:
python examples/online_serving/qwen3_omni/openai_realtime_client.py \
--url ws://localhost:8091/v1/realtime \
--model Qwen/Qwen3-Omni-30B-A3B-Instruct \
--input-wav input_16k_mono.wav \
--output-wav response.wav \
--output-text response.txt
The client dependency is websockets.
Protocol¶
Messages in both directions are JSON text frames. Audio carried inside an event is base64-encoded raw PCM16.
| Direction | Event | Purpose |
|---|---|---|
| Server to client | session.created | Confirms that the WebSocket connection is ready |
| Client to server | session.update | Selects and validates the served model |
| Client to server | input_audio_buffer.commit with final: false | Starts generation over the incoming stream |
| Client to server | input_audio_buffer.append | Appends base64 PCM16 audio |
| Client to server | input_audio_buffer.commit with final: true | Marks the end of input |
| Server to client | transcription.delta | Carries incremental response text |
| Server to client | transcription.done | Carries final text and token usage |
| Server to client | response.output_audio.delta | Carries incremental PCM16 response audio |
| Server to client | response.output_audio.done | Marks the end of response audio |
| Server to client | error | Reports an invalid event, model, or audio payload |
A minimal client sends events in this order:
{"type":"session.update","model":"Qwen/Qwen3-Omni-30B-A3B-Instruct"}
{"type":"input_audio_buffer.commit","final":false}
{"type":"input_audio_buffer.append","audio":"<base64-pcm16>"}
{"type":"input_audio_buffer.commit","final":true}
The initial non-final commit intentionally starts generation before all audio has arrived. Continue sending input_audio_buffer.append events while the engine is consuming the stream.
Audio Handling¶
- Input is mono PCM16 at 16 kHz for the Qwen3-Omni example.
response.output_audio.delta.audiocontains base64-encoded PCM16 bytes.- Read
sample_rate_hzfrom each audio event instead of assuming an output rate. Qwen3-Omni output is typically 24 kHz. - Concatenate audio deltas in receive order to construct the output waveform.
- Set
input_audio_buffer.commit.finaltotrueafter the last input chunk so the server can terminate the streaming request.
Availability and Limitations¶
The path is registered on the unified API server, but it is usable only when the loaded pipeline implements realtime audio input and produces compatible audio output. Unsupported deployments return an error event. The endpoint does not provide duplex session resume, playback acknowledgement, overlap policy, or barge-in controls.
See the Qwen3-Omni online serving example for concurrency options, chunk pacing, and per-delta audio debugging.