Skip to main content
When a call starts, Inkbox opens a WebSocket connection to your agent at the 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

  1. Inkbox connects to your client_websocket_url with an X-Call-Context header containing the call_id, phone_number, direction, and matching contacts. If the agent identity that owns this phone number has a signing key, the connection also includes X-Inkbox-Request-ID, X-Inkbox-Timestamp, and X-Inkbox-Signature headers.
The 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.
  1. 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.
  1. start event is sent to your agent with the call_control_id and media format details.
  2. Streaming begins. Text or audio flows bidirectionally depending on the mode.
  3. stop event 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 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)

start
transcript
barge_in
stop

Events you send (your agent → Inkbox)

text
stop

Audio format

Audio payloads are base64-encoded inside media 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:
The 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 receive barge_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, send transcript 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 with hangup_reason: "max_duration". See Rate Limits for organization-level limits.

Setting your stream URL

Configure client_websocket_url on a phone number so it’s used automatically for all auto-accepted calls:
JSON
Or provide a client_websocket_url per-call when placing outbound calls or responding to incoming call webhooks.