Skip to main content

Overview

Send text as your LLM produces it and get audio frames back as they render, over one WebSocket connection. Use this when you do not have the full text up front. If you do, use Synthesize Speech — same voices, same controls.
This endpoint is not yet enabled on the public API. A connection to wss://api.bland.ai/v2/tts/live currently fails the WebSocket handshake. Use Synthesize Speech until this page drops the notice.
Use a BTTS_V3 or newer voice. expressiveness and stability are calibrated for it. BTTS_V2 voices synthesize, but the controls are not tuned for them.

Authentication

Credentials are checked in this order:
  • ?token=<JWT> query parameter (recommended for browsers). Mint via Mint Stream Input Token.
  • Authorization: Bearer <api_key> header (server-side).
  • Sec-WebSocket-Protocol: bland.api_key.<key> subprotocol.
  • ?api_key=<key> query (deprecated, logged).

Protocol

Control frames are JSON text. Audio frames are binary, so tell them apart by WebSocket frame type. There is no container here — you always get bare frames in the encoding you asked for.

Client → Server messages

  • init is required as the first message. voice is a UUID (names are rejected).
    • audio.encoding defaults to pcm_s16le. mulaw is 8 kHz only, for telephony.
    • audio.sample_rate defaults to 48000, the rate BTTS V3 renders natively. Allowed: 8000, 16000, 24000, 44100, 48000.
    • controls.expressiveness and controls.stability are optional 0.01.0.
    • auto_flush (default true) triggers synthesis on sentence boundaries or when the buffer reaches auto_flush_char_threshold.
  • speak appends text. Setting flush: true renders the buffer immediately.
  • flush renders whatever is buffered.
  • close renders any remaining text, sends done, then closes.

Server → Client messages

Limits and guardrails

Error codes


Example

Node (ws)

Docs for agents: llms.txt