Connect a custom AI voice agent to Vobiz with bidirectional WebSocket audio, direction-specific formats, playback, checkpoints, and barge-in.
Use a bidirectional <Stream> when you want your own WebSocket server to run the speech-to-text, agent, text-to-speech, and barge-in logic for a call.
<Stream> XML elementReturn this XML from your call's Answer URL:
xml<?xml version="1.0" encoding="UTF-8"?> ```xml <Response> <Stream bidirectional="true" keepCallAlive="true" statusCallbackUrl="https://your-domain.com/stream-status" statusCallbackMethod="POST"> wss://your-domain.com/ws </Stream> </Response>
The WebSocket URL is the text content of `<Stream>`. Use `wss://` in production.
## Understand the two audio directions
```text
Inbound stream audio
Caller -> Vobiz -> your WebSocket application
Configured by <Stream contentType> and reported by start.mediaFormat
Outbound playback audio
Your WebSocket application -> Vobiz -> caller
Configured by playAudio.media.contentType and playAudio.media.sampleRate
Your inbound and outbound formats can differ. For example, you can decode inbound L16/8 kHz audio and send an outbound L16/24 kHz TTS response.
⚠️ Warning: Do not put
contentType="audio/x-l16;rate=24000"on<Stream>to configure 24 kHz TTS playback. That attribute controls inbound Vobiz-to-application audio. Declare 24 kHz on the outboundplayAudioevent.
Vobiz sends these events to your application:
| Event | Purpose |
|---|---|
start | Provides callId, streamId, tracks, and the inbound mediaFormat. |
media | Carries Base64-encoded inbound audio. |
playedStream | Confirms playback reached a named checkpoint. |
clearedAudio | Confirms queued outbound playback was cleared. |
Your application sends these commands to Vobiz:
| Command | Purpose |
|---|---|
playAudio | Queue outbound audio for the caller. |
checkpoint | Mark playback progress after an utterance. |
clearAudio | Remove queued audio when the caller interrupts. |
stop | End the streaming session. |
When the call ends, handle the WebSocket close event. Do not wait for an inbound { "event": "stop" } message.
Save the streamId and initialize your decoder from the start event:
json{ "event": "start", "start": { "callId": "CALL_ID", "streamId": "STREAM_ID", "tracks": ["inbound"], "mediaFormat": { "encoding": "audio/x-l16", "sampleRate": 8000 } } }
Supported inbound formats are:
| Format | Sample rate |
|---|---|
| L16 | 8000 or 16000 Hz |
| μ-law | 8000 Hz |
Base64-decode each media.payload, then pass the raw audio to a decoder or STT service configured for start.mediaFormat. Do not assume the inbound format matches your outbound TTS format.
Vobiz accepts these outbound playAudio formats:
| Format | Sample rate |
|---|---|
| L16 | 8000, 16000, or 24000 Hz |
| μ-law | 8000 Hz |
Send raw mono audio without a WAV, MP3, or other file header:
json{ "event": "playAudio", "streamId": "STREAM_ID", "media": { "contentType": "audio/x-l16", "sampleRate": 24000, "payload": "BASE64_ENCODED_RAW_L16_AUDIO" } }
The payload must genuinely match the declared format. If your TTS provider returns audio at another rate or in a container, convert it before Base64 encoding. Changing only sampleRate does not resample the audio.
Send approximately 20–60 ms per playAudio message for responsive barge-in. This is a recommendation, not a protocol requirement.
After the final playback chunk for an utterance, send a checkpoint:
json{ "event": "checkpoint", "streamId": "STREAM_ID", "name": "response-1" }
When playback reaches it, Vobiz sends playedStream with the same name. If the caller interrupts, send:
json{ "event": "clearAudio", "streamId": "STREAM_ID" }
Cleared or interrupted playback may not produce playedStream. Add a timeout so your application does not wait indefinitely.
textCaller audio -> start.mediaFormat -> Base64 decode -> STT -> agent or LLM -> TTS at a supported outbound rate -> raw mono audio -> Base64 encode -> playAudio -> caller
Your STT and TTS providers may require different formats. Convert only at the boundary that needs it, and keep the declared metadata synchronized with the real bytes.
ℹ️ Note: A 24 kHz
playAudiopayload does not guarantee 24 kHz audio at the handset. The phone-facing carrier, SIP, or PSTN leg may use a lower-rate codec.
Confirm the real payload rate matches playAudio.media.sampleRate. Remove file headers and ensure the audio is mono.
Send clearAudio as soon as your voice-activity detector confirms barge-in. Keep playback chunks small so less audio remains queued.
Set bidirectional="true" and keepCallAlive="true". For bidirectional streams, use audioTrack="inbound" or omit audioTrack.
Handle the WebSocket close event. Vobiz does not send an inbound stop JSON event when the call ends.
Connect 3CX PBX to Vobiz SIP trunking for inbound and outbound calling across 130+ countries - configure a generic SIP trunk in minutes.
Connect an Agora Conversational AI agent to Vobiz SIP trunking - add a Vobiz number to Agora for outbound campaigns and route inbound calls to your agent, including India and 130+ countries.
Bolna ships Vobiz as a built-in telephony provider. Paste two credentials into the Providers screen and your agents place and answer calls on numbers in 130+ countries, reaching 190, with audio streaming rather than a SIP trunk.
We use cookies to run this site and, with your permission, to understand how it's used. Read our Cookie Policy.