Sequence diagram
Events at a glance
Client → server
Server → client
Session initialization
Immediately after the WebSocket opens, send asession.update to configure the agent. You have two ways to configure:
- Stored agent. Send
{ "agent_id": "<id>" }to bind to an agent created via the Agents REST API. The storedsystem_prompt,greeting,tools,input, andoutputare applied server-side. - Inline configuration. Omit
agent_idand sendsystem_prompt,greeting,tools,input, andoutputdirectly.
session.ready once the session is established:
Sending audio
Aftersession.ready, stream audio to the agent as input.audio events. Each event carries a base64-encoded chunk of PCM16 audio:
session.input.format. See Audio format for the full format specification and Encoding for supported encodings.
User turn
When turn detection decides the user has started speaking, the server emitsinput.speech.started. As speech continues, partial transcripts stream back as transcript.user.delta. When the user stops speaking, the server emits input.speech.stopped followed by a final transcript.user:
Agent reply
Once the user turn ends, the agent generates a reply. Every reply is bracketed byreply.started and reply.done. In between, audio streams back as reply.audio events (base64 PCM16), and the full text arrives as transcript.agent after all audio has been delivered:
transcript.agent is emitted after the final reply.audio chunk, so it can be used to display the agent’s reply once playback completes.Tool calls
If the agent decides to invoke a registered tool, the server emits atool.call event. The current reply ends with reply.done, and the client is expected to run the tool and return the result via tool.result. A fresh reply.started … reply.done cycle follows once the tool result is received:
Updating configuration mid-session
You can send anothersession.update at any time to change mutable fields such as system_prompt, input.turn_detection, or output.volume. The server acknowledges with session.updated. Changing immutable fields (for example greeting, output.voice, or output.format) raises immutable_field. See Mutability after session.ready.
Session termination
To end a session cleanly, sendsession.end. The server flushes any in-flight events, emits session.ended, then closes the WebSocket with code 1000:
Errors
If the session fails at any point, the server sends asession.error event and closes the connection: