client_websocket_url you configured on the phone number or provided when placing the call. This connection carries the live call data between your agent and the caller for the duration of the call.
What flows over this connection (text, audio, or both) depends on how your agent configures itself. Inkbox can handle text-to-speech (TTS), speech-to-text (STT), or both on your behalf. See Choosing a mode below.
Connection flow
- Inkbox connects to your
client_websocket_urlwith anX-Call-Contextheader containing thecall_id,phone_number,direction, and matching contacts. If the agent identity that owns this phone number has a signing key, the connection also includesX-Inkbox-Request-ID,X-Inkbox-Timestamp, andX-Inkbox-Signatureheaders.
X-Call-Context value is canonical JSON:
contacts is always present and may be empty. A contact’s name is null when it has no name on file — a contact created automatically from an inbound call has an id and memories before anyone gives it a name, and name never falls back to the caller’s phone number. Check it before having your agent greet someone by name. Memories are ordered newest first. The header value is limited to 8,000 UTF-8 bytes; if older memories are omitted to fit that limit, memories_truncated is true. Verify the signature against the exact X-Call-Context header value before parsing it.
- Your agent accepts the WebSocket and declares its capabilities with response headers:
If you omit the speech headers, both default to
true, so Inkbox handles STT and TTS. Audio defaults to PCMU at 8 kHz.
-
startevent is sent to your agent with thecall_control_idand media format details. - Streaming begins. Text or audio flows bidirectionally depending on the mode.
-
stopevent is sent when the call ends.
Choosing a mode
The combination of the two speech headers gives you four configurations. Use the selector below to explore what each mode looks like, including the exact WebSocket events your agent sends and receives.- Inkbox handles STT + TTS
- Inkbox handles TTS only
- Inkbox handles STT only
- Full audio bridge
Inkbox transcribes the caller and synthesizes your responses. Your agent only deals with text.
Simplest setup. Ideal when your agent is a text-based LLM and you want Inkbox to handle all audio processing.
WebSocket response headers
Your agent declares this configuration by setting these headers when accepting the WebSocket connection:Events you receive (Inkbox → your agent)
starttranscriptbarge_instopEvents you send (your agent → Inkbox)
textstopAudio format
Audio payloads are base64-encoded insidemedia events. Choose the format with the X-Inkbox-Audio-Format header in your WebSocket handshake response:
The selected format applies to audio in both directions. The examples above use the default. To use PCM16, return:
start.media_format then reports encoding: "L16", sample_rate: 16000, and channels: 1. Despite the L16 label, PCM16 samples on this WebSocket are little-endian. Unsupported or repeated audio-format headers cause the connection to close.
Interruptions
When you receivebarge_in, stop generating the current response and stop sending its text or audio. The trigger is interim_transcript or final_transcript for caller speech. Its text contains the recognized speech or an indication that the caller started speaking. A cancel_turn trigger requests cancellation and can have empty text. The tts_interrupted flag reports whether playback was interrupted.
Send a clear event to discard audio already queued for playback to the caller:
clear travels from your agent to Inkbox. Stop sending the old response before clearing its queued audio.
Transcripts
Inkbox stores call transcripts as the call progresses. When Inkbox handles STT, it captures caller transcripts automatically. When your agent handles STT or TTS, sendtranscript events for the speech it transcribes or generates. You can retrieve transcripts after the call via the Transcripts API.
Call duration
Each call has a maximum duration of 10 minutes. When the limit is reached, Inkbox hangs up the call withhangup_reason: "max_duration". See Rate Limits for organization-level limits.
Setting your stream URL
Configureclient_websocket_url on a phone number so it’s used automatically for all auto-accepted calls:
JSON
client_websocket_url per-call when placing outbound calls or responding to incoming call webhooks.
