Skip to main content
The WebSocket API provides low-level access to Deepslate Realtime for server-side integrations. Use this for telephony backends, SIP gateways, or custom voice pipelines.
This interface is for server-side use only. End users should connect through WebRTC or your application’s frontend. Never expose your API key to clients.

Prerequisites

Connect

Connect to the WebSocket endpoint with your API key in the headers:

Initialize Session

The first message must be an InitializeSessionRequest to configure audio format, VAD, and model behavior:
Set supportsPlaybackReporting: true when your client will report how many audio bytes it has played. Reporting gives you accurate context truncation when the caller interrupts mid-response. See Playback Position Reporting.
See the API Reference for all configuration options including TTS providers and tool definitions.

Send Audio

Stream audio as UserInput messages. Audio must match your inputAudioLine configuration:
The mode field controls how the input interacts with ongoing inference: You can also send text input instead of audio by using textData in place of audioData.
Audio format must exactly match your session configuration. For 16-bit signed PCM at 16kHz mono, each sample is 2 bytes, little-endian.

Handle Responses

The server sends ClientBoundMessage with one of several payload types.
Text and audio output
  • ModelTextFragment — emitted for every assistant turn, whether or not TTS is configured. Contains streamed text tokens as the model generates them. When TTS is configured, they arrive ahead of speech synthesis.
  • ModelAudioChunk — sent only when a TTS provider is configured. Contains the synthesized audio. The text that goes with it arrives on ModelSpeechProgress.
  • ModelSpeechProgress — emitted continuously while TTS audio plays. Reports which part of the turn’s text has become audible.
Most response messages carry a turnId identifying the assistant turn they belong to. Turn IDs are 0-based, so 0 is a real turn, not a missing value. ResponseBegin, ResponseEnd, ModelSpeechProgress and InferenceComplete always carry one. On ModelTextFragment and ModelAudioChunk it is optional. When it is absent, attribute the message to the turn opened by the most recent ResponseBegin.

Handle Interruptions

When the user starts speaking, the server sends PlaybackClearBuffer proactively to ensure any ongoing playback is stopped. This is sent regardless of whether there is currently TTS playback. You should immediately discard any queued audio that hasn’t played yet:

Trigger Inference

Use TriggerInference to make the model respond immediately without waiting for user speech. The primary use case is generating a greeting when the session opens.
TriggerInference is designed for generating a greeting before any user input. Using it directly after a model response may produce unpredictable results.

Reconfigure Session

Use ReconfigureSessionRequest to update the input audio format or system prompt mid-session without reconnecting. You can update either field or both.
Reconfiguration is not guaranteed to be seamless. There may be brief audio glitches or dropped audio around the transition.

Direct Speech

Use DirectSpeech to speak text via TTS immediately, bypassing the LLM. Any active inference is cancelled and the audio buffer is cleared before the text is spoken.
When includeInHistory is false, the message is marked as ephemeral in the chat history — it is audible to the user but invisible to the LLM’s context. When uninterruptable is true, the utterance plays to completion and overlapping user speech is ignored until playback finishes. It defaults to false (interruptible). Use it for compliance announcements, such as notifying the user that they are speaking with an AI.

Conversation Query

Use ConversationQuery to run a one-shot LLM inference over the current conversation history without modifying it. The result is returned as a ConversationQueryResult. This is useful for side tasks like summarization or classification that should not affect the ongoing conversation.
At least one of prompt or instructions must be provided. If prompt is absent, the session’s current system prompt is used.

Playback Position Reporting

Send PlaybackPositionReport messages regularly as audio plays. This gives the server accurate data to truncate the LLM context to exactly what the caller heard when they interrupt. Counts are per turn, not per session. Use the turnId from the ModelAudioChunk the bytes came from, falling back to the current turn when the chunk omits it, and keep a separate total for each turn. turnId on the report is itself optional, and omitting it is not the same as sending 0. Turn IDs are 0-based, so a report without one is read as coming from a client that predates turn correlation, and the server applies it to the current response instead. Always set it.
Set supportsPlaybackReporting: true in InitializeSessionRequest when you intend to send these. Without playback reporting, the server falls back to elapsed-time estimation for context truncation, which is less precise. The same estimate drives audio_bytes_played and the pacing of ModelSpeechProgress, so reporting real positions tightens that stream too.

Track Turn Content

TurnSnapshot carries the server’s authoritative view of a single turn.
  • Snapshots are not guaranteed to be monotonic. A turn can produce several, and content can be rolled back.
  • is_final means immutable, not permanent. Once a snapshot arrives with isFinal: true, that turn’s content will not change again and no further snapshots for it will arrive. The turn can still leave the model’s context later through truncation, which ContextTruncated reports separately.

Export Chat History

Use ExportChatHistoryRequest to retrieve the full conversation history at any point. Set awaitPending: true to wait for any in-flight transcriptions to finish before the history is returned.
Each ChatMessage includes a role (SYSTEM, USER, or ASSISTANT), ordered content blocks, a deliveryStatus (DELIVERY_COMPLETE, DELIVERY_INTERRUPTED), and an ephemeral flag for messages spoken via DirectSpeech with includeInHistory: false. Audio content blocks (input_audio and tts_audio) include a transcription string that is populated asynchronously for user audio turns.

Tool Calling

Enable the model to call functions by defining tools and handling requests.

Define Tools

Send an UpdateToolDefinitionsRequest to register available tools. Each tool needs a name, description, and JSON Schema parameters:
Calling UpdateToolDefinitionsRequest replaces all existing tools. Send an empty array to clear all tools.

Handle Tool Requests

When the model wants to use a tool, you receive a ToolCallRequest. You must respond with a ToolCallResponse:
Every ToolCallRequest must receive a ToolCallResponse, even if the tool execution fails. The model waits for the response before continuing.

Complete Example

A Node.js client with microphone input. It configures no TTS provider, so the server returns text rather than speech. The client does not play audio and therefore does not report playback positions; see Playback Position Reporting for that side.

Next Steps

API Reference

Full message schemas, all configuration options, and tool calling

WebRTC

Browser-based integration for end-user applications

LiveKit Plugin

LiveKit Agents plugin for Deepslate integration

Pipecat Plugin

Pipecat framework plugin for Deepslate integration