Skip to main content
PrerequisitesTo use stream events, you must:
  • Set bidirectional="true" on the <Stream> element.
  • Have an active WebSocket connection established by Vobiz.
  • Send events as JSON messages through the WebSocket.

Open the Stream Events Visualizer

Step through a complete bidirectional sequence and inspect each payload as it moves between Vobiz and your application.

1. Bidirectional XML setup

Bidirectional streaming is the prerequisite for sending any command back to Vobiz. Configure it on the <Stream> XML element:
Enable bidirectional audio streaming
See Initiate a Stream for the full set of <Stream> attributes.

2. How events flow

Two directions, seven events total. Each event is documented in detail in the Typical event sequence below. App → Vobiz - commands you send to control the call Vobiz → App - events your handler receives
There is no inbound stop event. Vobiz does not send { "event": "stop" } when the call ends - the WebSocket simply closes. Treat the WebSocket close event as your end-of-stream signal. See Detecting end of stream for the lifecycle details.stop exists only as an outbound command - see Server-initiated stop.
playedStream is conditional. It is only emitted if the audio queued before the matching checkpoint played to completion. If playback fails or is interrupted (e.g. by a clearAudio), you will not receive the ack.

3. Typical event sequence

A complete interactive turn - Vobiz opens the stream, your app greets the caller, the caller speaks, your app barges in with a new response.
1

Vobiz → App · start

Fires once, immediately after Vobiz upgrades the WebSocket. Use it to set up per-call state (transcribers, recording paths, etc). The call/stream identifiers live inside the nested start object - not at the top level.
start.mediaFormat reflects the inbound contentType selected on <Stream>. Decode every incoming media.payload using this value. It does not set the format for outbound playAudio events.
2

App → Vobiz · playAudio (greeting)

Queue outbound audio for playback. The payload must match the media.contentType and media.sampleRate declared in this event. The outbound format can differ from the inbound start.mediaFormat when both formats are supported.
Use approximately 20–60 ms chunks for responsive barge-in. For a 20 ms chunk, μ-law/8 kHz uses 160 raw bytes and L16/8 kHz uses 320 raw bytes.
Include the streamId from the start event in customer-facing playAudio, clearAudio, checkpoint, and stop commands.
3

App → Vobiz · checkpoint

Send right after the last playAudio chunk of an utterance. Vobiz replies with playedStream once it has actually delivered the queued audio to the caller.
4

Vobiz → App · playedStream

Acknowledgment that the audio queued before the checkpoint finished playing to the caller. The payload is just event + name - there is no streamId field.
This is the uninterrupted-playback branch. In the Stream Events Visualizer, the caller barges in before the greeting finishes. That branch skips this acknowledgment, sends clearAudio, and continues after clearedAudio.
The name echoes the name you set in the matching checkpoint.
5

Vobiz → App · media (caller audio)

One frame every 20 ms while the caller is on the line (~50 per second per track). media.payload is base64-encoded raw audio in the encoding declared by start.mediaFormat.
6

App → Vobiz · clearAudio (barge-in)

Drops everything queued in Vobiz that hasn’t been streamed to the caller yet. Use this the moment your VAD detects the caller speaking over the bot.
7

Vobiz → App · clearedAudio

Acknowledgment that the queued playback audio was flushed.
8

App → Vobiz · playAudio (new response)

Send the fresh response. Repeat steps 2–4 (playAudiocheckpointplayedStream) for each utterance.
9

App → Vobiz · stop (end the stream)

When your agent is done, send a stop packet. The stream stops immediately and Vobiz proceeds to the next XML element in your response. If there is no next element, Vobiz hangs up the call with HangupCauseCode=4010 (“End Of XML Instructions”).
There is no inbound stop ack - the WebSocket close itself confirms it. Full webhook flow and the Hangup payload are in Server-initiated stop below.

4. Ending the stream

Detecting end of stream

When the call ends, the last media frame arrives and the WebSocket closes. There is no in-band JSON stop event from Vobiz. The end-of-stream signals are, in order of arrival:
  1. The WebSocket close event - the canonical signal, universal across every termination path.
  2. (Server-initiated stops only) Event=StopStream POSTed to statusCallbackUrl.
  3. Event=Hangup POSTed to hangup_url - the authoritative “call is over” signal regardless of who ended the call.
Do not detect the end of a call by inspecting media.payload. Silence can appear at any point in a call and is not an end-of-stream marker.Do not wait for an inbound { "event": "stop" } on the WebSocket - Vobiz does not emit one.The StopStream status callback is only observed when the server initiates the stop (it does fire reliably in that case). It does not fire when the caller hangs up or the call is killed mid-stream - fall back to the WebSocket close event and the Hangup webhook in those cases.Flush any in-memory recording/transcript buffers from your WebSocket close handler.
For a runnable reference that demonstrates this flow end-to-end (mid-stream frames → final frame → WAV flush on close), see the Bun Media Stream Server.

Server-initiated stop

You can terminate the stream from your side by sending a stop command over the WebSocket. The stream stops immediately and Vobiz proceeds to the next XML element in your response:
  • If there is a next XML element (e.g. <Speak>, <Dial>, <Redirect>), Vobiz executes it. The call continues without <Stream>.
  • If there is no next element, Vobiz hangs up the call. The Hangup webhook will report HangupCauseCode=4010 (“End Of XML Instructions”) and HangupSource=Vobiz. You do not need to follow <Stream> with <Hangup/> for this - it’s automatic.
Producer snippet
What happens after you send the stop: You don’t need to wait for any WebSocket reply - once you’ve sent the stop, the WS closes and the lifecycle webhooks (if applicable) follow. There is no matching inbound stop JSON event; the WebSocket close itself is your acknowledgment. The REST equivalent of this is POST /audio-streams/.../stop.

5. Node.js handler

A minimal reference handler that wires up the four most common code paths: receiving start, queueing playAudio + checkpoint, processing inbound media, and reacting to playedStream. Use it as a skeleton; replace the bodies with your STT/LLM/TTS pipeline.
Sending events from your WebSocket server

6. Runnable example

Use the Bun Media Stream Server to inspect start and media events, handle WebSocket closure, and save inbound audio for local testing.