Converse

Developer guide

WebSocket API

The advanced path for applications that need direct protocol control. Your client owns audio conversion, pacing, playback, echo cancellation and reconnects.

← Choose another integration

Use the generated realtime reference for a message index or download the AsyncAPI contract.

WebSocket API

Connect to wss://converse.trelis.com/ws. Trusted non-browser clients may authenticate with Authorization: Bearer ck_…; all clients may include api_key in their first JSON frame.

Start frame

{
  "type": "start",
  "session_id": "your-unique-session-id",
  "api_key": "ck_or_scoped_key",
  "audio": { "sr": 16000 },
  "mode": { "kind": "converse", "web_search": false },
  "client": {
    "user": "optional-stable-user-id",
    "timezone": "Europe/Dublin",
    "capabilities": []
  }
}
FieldRequiredDescription
typeYesMust be start.
session_idYesYour 1–64 character correlation ID; must match a scoped key.
api_keyIf no auth headerPersistent or scoped credential.
audio.srYesInput sample rate. Use 16000.
modeYesConversation configuration.
clientNoUser metadata and implemented protocol capabilities.

Audio frames

DirectionEncodingRecommended frame size
Client → ConverseBinary PCM16 little-endian, mono, 16 kHz20–100 ms, paced in real time
Converse → clientBinary Float32 little-endian, mono, 16 kHzPlay in arrival order

JSON and binary frames share the same socket. A normal reply is turn, zero or more binary audio frames, utterance, then done. User transcripts arrive as asr.

Client control frames

FramePurpose
{"type":"reset"}Clear conversation context.
{"type":"set_voice","voice":"key"}Change voice for the next reply.
{"type":"tool_result","id":"…","content":{…}}Resolve a tool call.
{"type":"tool_progress","id":"…","note":"…"}Report non-final tool progress.
{"type":"tool_cancel","id":"…"}Cancel tool work.
{"type":"client_event","event":"playback_stopped",…}Report actual speaker playback after an interruption.

Playback obligation

Clients that play assistant audio must track queued and discarded audio. After interrupted, report how much audio was not heard:

{
  "type": "client_event",
  "event": "playback_stopped",
  "remaining_ms": 150,
  "discarded_ms": 420,
  "barge_seq": 3
}

Advertise playback_pause_v1 in client.capabilities only if your player can hold and resume already-scheduled audio. Otherwise Converse uses immediate interruption events.

client.audio_frontend is optional diagnostic metadata describing the active microphone/AEC path; use unknown until it is known.

Echo barge_seq from the interruption. Converse may respond with a corrected utterance carrying the same sequence; replace the earlier assistant transcript for that interruption. The browser SDK handles this playback protocol automatically. Python and raw WebSocket clients must implement it when they perform real playback.

Client tools

Declare tools in mode.tools. Tools are available in Converse mode and may be combined with web_search. The model chooses whether to answer directly, search, or call one or more client tools.

"tools": [{
  "name": "lookup_order",
  "description": "Look up an order by its customer-visible ID.",
  "parameters": {
    "type": "object",
    "properties": { "order_id": { "type": "string" } },
    "required": ["order_id"]
  },
  "read_only": true,
  "requires_permission": false,
  "timeout": 30
}]
FieldDefaultContract
nameRequiredUnique, non-empty tool name.
description""Tells the model when and how to use the tool.
parametersEmpty object schemaJSON Schema for args.
read_onlyfalsetrue lets Converse start the call early for speed. Use it only for harmless, cheap lookups. Leave it false for anything that changes data, sends something, spends meaningful money or accesses sensitive data.
requires_permissionfalseHold the exact call until the user clearly approves it. Converse asks naturally, verifies the reply and executes nothing when approval or scope is unclear.
timeout30 secondsResult deadline; minimum 1 second, maximum 120 seconds.

When requires_permission is true, the first call is held inside Converse and is not sent to your host. A clear approval releases the original name and arguments exactly once; refusal discards it; ambiguity remains pending for clarification. Changed arguments create a new permission request. Pending permission IDs are one-time, session-scoped and expire after five minutes by default. Permission questions and acknowledgements are generated naturally from the conversation.

Converse calls the host:

{"type":"tool_call","id":"turn3-fc1","name":"lookup_order","args":{"order_id":"A123"}}

Complete exactly once with a result or client cancellation:

{"type":"tool_result","id":"turn3-fc1","content":{"speak":"The order shipped.","data":{"status":"shipped"},"handle":"order-A123"}}
{"type":"tool_cancel","id":"turn3-fc1"}

For longer work, progress does not resolve the call or interrupt playback:

{"type":"tool_progress","id":"turn3-fc1","note":"checking the carrier"}
  • Result content is limited to 16 KiB of compact UTF-8 JSON by default. Oversized results still resolve, but Converse replaces them with bounded content containing tool_result_truncated, original_bytes and a preview.
  • Progress notes are limited to 500 characters and 12 notes per call.
  • A server tool_cancel asks the host to stop promptly because the result is no longer usable.
  • Barge-in never cancels tool work. It stops the spoken reply; the tool may continue and its result remains available to the next turn. If users need to stop work, expose a separate effectful stop tool whose description tells the model when to use it.
  • Keep verbose logs and artifacts in your own system. Return a short spoken summary, structured data and, when useful, a handle or URL.

Errors, reconnects and limits

detailWhat to do
unauthorizedReplace a missing, unknown, expired or revoked credential.
invalid session_idUse a safe non-empty identifier and match the scoped credential.
insufficient creditAdd credit in API & Billing.
too many concurrent sessionsClose the existing session or wait for it to end.
server busy — try again shortlyRetry with exponential backoff.
server restarting — try again shortlyRetry shortly.
voice pipeline unavailable — try again shortlyRetry with backoff and surface a temporary-service message.
  • One concurrent session per account by default.
  • Each connection is capped at two hours.
  • Billing is $3.00 per connected hour, metered per second with partial seconds rounded up.
  • An abnormal browser transport loss is retried automatically; the new connection starts a new conversation.
  • A clean server close ends the session and is not automatically reconnected.

To validate a key without opening a billable session, connect and send {"type":"auth","api_key":"ck_…"}. A valid key receives {"type":"ok"} and the socket closes.

Platform support

PlatformStatusWhat you provide
Desktop Chrome / EdgeRecommended and production validatedBrowser SDK and scoped credential route.
Desktop FirefoxProtocol support; live validation pendingBrowser SDK and scoped credential route.
Safari / iOS WebKitNot yet a supported production targetContact us before committing to this path.
Python service / telephony / custom hardwareSupported headless transportCapture, pacing, playback and echo cancellation.
Raw WebSocketSupported advanced integrationThe complete media and session lifecycle.
Native desktop / mobile SDKsPlannedNot available yet.