curl \
--request POST \
--url "https://api.breeze.blue/v1/text-to-speech/voc_xeh3w54cqvnp/realtime-sessions" \
--header "xi-api-key: $BREEZE_API_KEY" \
--header "Content-Type: application/json" \
--data '{
"model_id": "breeze-tts-2",
"language_code": "en",
"instructions": "Keep turns responsive and conversational.",
"voice_settings": {
"guidance_scale": 4.0
},
"inactivity_timeout_seconds": 30,
"enable_logging": true
}'import asyncio
from pathlib import Path
import os
from breeze_blue import BreezeBlue
client = BreezeBlue(api_key=os.environ["BREEZE_API_KEY"])
session = client.text_to_speech.create_realtime_session(
voice_id="voc_xeh3w54cqvnp",
model_id="breeze-tts-2",
)
async def main() -> None:
async with client.text_to_speech.connect_realtime(
voice_id="voc_xeh3w54cqvnp",
client_secret=session["client_secret"],
websocket_url=session["websocket_url"],
direct_websocket_url=session.get("direct_websocket_url"),
) as connection:
async def consume_audio() -> bytes:
audio = bytearray()
async for event in connection:
if event["type"] == "audio":
audio.extend(event["audio"])
elif event["type"] == "error":
raise RuntimeError(event["message"])
elif event["type"] == "turn.done":
return bytes(audio)
raise RuntimeError("Realtime session closed before turn.done")
consumer = asyncio.create_task(consume_audio())
await connection.start_turn("turn_1")
await connection.append_text("Hello from Breeze.")
await connection.flush()
await connection.end_turn()
Path("out.pcm").write_bytes(await consumer)
asyncio.run(main())import { writeFile } from "node:fs/promises";
import { BreezeBlueClient } from "@breeze.blue/sdk";
const client = new BreezeBlueClient({
apiKey: process.env.BREEZE_API_KEY!,
});
const session = await client.textToSpeech.realtime.createSession(
"voc_xeh3w54cqvnp",
{ modelId: "breeze-tts-2" },
);
const connection = await client.textToSpeech.realtime.connect(
"voc_xeh3w54cqvnp",
{
clientSecret: session.clientSecret,
websocketUrl: session.websocketUrl,
directWebsocketUrl: session.directWebsocketUrl,
},
);
const consumer = (async () => {
const pcmChunks: Uint8Array[] = [];
for await (const message of connection) {
if (message.type === "audio") pcmChunks.push(message.audio);
if (message.type === "error") throw new Error(message.message);
if (message.type === "turn.done") return pcmChunks;
}
throw new Error("Realtime session closed before turn.done");
})();
connection.startTurn("turn_1");
connection.appendText("Hello from Breeze.");
connection.flush();
connection.endTurn();
const pcmChunks = await consumer;
await writeFile(
"out.pcm",
Buffer.concat(pcmChunks.map((chunk) => Buffer.from(chunk))),
);
connection.close();{
"client_secret": "<string>",
"websocket_url": "<string>",
"expires_at": "<string>",
"direct_websocket_url": "<string>",
"audio_format": {
"codec": "pcm_s16le",
"sample_rate": 24000,
"channels": 1,
"sample_width_bits": 16
}
}{
"code": "<string>",
"detail": "<string>",
"error": "<string>",
"ok": false,
"meta": {}
}{
"code": "<string>",
"detail": "<string>",
"error": "<string>",
"ok": false,
"meta": {}
}{
"code": "<string>",
"detail": "<string>",
"error": "<string>",
"ok": false,
"meta": {}
}{
"code": "<string>",
"detail": "<string>",
"error": "<string>",
"ok": false,
"meta": {}
}{
"code": "<string>",
"detail": "<string>",
"error": "<string>",
"ok": false,
"meta": {}
}Create realtime TTS session
Create a short-lived browser-safe token for the realtime text-to-speech WebSocket. This HTTP operation only creates the session. Official SDKs and the CLI prefer the optional query-free direct_websocket_url and fall back to websocket_url; wait for session.ready, and then exchange turn events and binary PCM audio. While no turn is active, send session.update with non-empty instructions (up to 1,000 characters) and wait for session.updated; the confirmed instructions apply starting with the next turn. See the Realtime TTS WebSocket guide for complete raw WebSocket, SDK, browser playback, and CLI examples.
curl \
--request POST \
--url "https://api.breeze.blue/v1/text-to-speech/voc_xeh3w54cqvnp/realtime-sessions" \
--header "xi-api-key: $BREEZE_API_KEY" \
--header "Content-Type: application/json" \
--data '{
"model_id": "breeze-tts-2",
"language_code": "en",
"instructions": "Keep turns responsive and conversational.",
"voice_settings": {
"guidance_scale": 4.0
},
"inactivity_timeout_seconds": 30,
"enable_logging": true
}'import asyncio
from pathlib import Path
import os
from breeze_blue import BreezeBlue
client = BreezeBlue(api_key=os.environ["BREEZE_API_KEY"])
session = client.text_to_speech.create_realtime_session(
voice_id="voc_xeh3w54cqvnp",
model_id="breeze-tts-2",
)
async def main() -> None:
async with client.text_to_speech.connect_realtime(
voice_id="voc_xeh3w54cqvnp",
client_secret=session["client_secret"],
websocket_url=session["websocket_url"],
direct_websocket_url=session.get("direct_websocket_url"),
) as connection:
async def consume_audio() -> bytes:
audio = bytearray()
async for event in connection:
if event["type"] == "audio":
audio.extend(event["audio"])
elif event["type"] == "error":
raise RuntimeError(event["message"])
elif event["type"] == "turn.done":
return bytes(audio)
raise RuntimeError("Realtime session closed before turn.done")
consumer = asyncio.create_task(consume_audio())
await connection.start_turn("turn_1")
await connection.append_text("Hello from Breeze.")
await connection.flush()
await connection.end_turn()
Path("out.pcm").write_bytes(await consumer)
asyncio.run(main())import { writeFile } from "node:fs/promises";
import { BreezeBlueClient } from "@breeze.blue/sdk";
const client = new BreezeBlueClient({
apiKey: process.env.BREEZE_API_KEY!,
});
const session = await client.textToSpeech.realtime.createSession(
"voc_xeh3w54cqvnp",
{ modelId: "breeze-tts-2" },
);
const connection = await client.textToSpeech.realtime.connect(
"voc_xeh3w54cqvnp",
{
clientSecret: session.clientSecret,
websocketUrl: session.websocketUrl,
directWebsocketUrl: session.directWebsocketUrl,
},
);
const consumer = (async () => {
const pcmChunks: Uint8Array[] = [];
for await (const message of connection) {
if (message.type === "audio") pcmChunks.push(message.audio);
if (message.type === "error") throw new Error(message.message);
if (message.type === "turn.done") return pcmChunks;
}
throw new Error("Realtime session closed before turn.done");
})();
connection.startTurn("turn_1");
connection.appendText("Hello from Breeze.");
connection.flush();
connection.endTurn();
const pcmChunks = await consumer;
await writeFile(
"out.pcm",
Buffer.concat(pcmChunks.map((chunk) => Buffer.from(chunk))),
);
connection.close();{
"client_secret": "<string>",
"websocket_url": "<string>",
"expires_at": "<string>",
"direct_websocket_url": "<string>",
"audio_format": {
"codec": "pcm_s16le",
"sample_rate": 24000,
"channels": 1,
"sample_width_bits": 16
}
}{
"code": "<string>",
"detail": "<string>",
"error": "<string>",
"ok": false,
"meta": {}
}{
"code": "<string>",
"detail": "<string>",
"error": "<string>",
"ok": false,
"meta": {}
}{
"code": "<string>",
"detail": "<string>",
"error": "<string>",
"ok": false,
"meta": {}
}{
"code": "<string>",
"detail": "<string>",
"error": "<string>",
"ok": false,
"meta": {}
}{
"code": "<string>",
"detail": "<string>",
"error": "<string>",
"ok": false,
"meta": {}
}Continue building
Write instructions
Realtime text to speech
Convert text to speech
Authorizations
Breeze Developer API key.
Path Parameters
Voice ID to use for speech generation. See List voices.
Body
Model ID for speech generation. Selected automatically when omitted. See List models.
1 - 120ISO 639-1 two-letter language code supported by the selected model. See supported language codes.
2^[A-Za-z]{2}$Initial performance instructions, written in the same language as the input text. See Updating instructions.
Optional realtime voice settings. See Voice settings.
Show child attributes
Show child attributes
Idle timeout for the WebSocket session. Defaults to 30 seconds and is capped at 180 seconds.
1 <= x <= 180Whether realtime turns should be stored in generation history.
Response
Realtime WebSocket session token and compatible transport URLs.
Short-lived token for browser WebSocket connections.
WebSocket URL including the client_secret query parameter.
ISO-8601 expiration timestamp for the client secret.
Optional direct WebSocket URL without credentials in its query. Authenticate with the documented WebSocket subprotocols.
Fixed realtime audio stream format.
Show child attributes
Show child attributes

