Stream speech output
POST https://api.kittenml.com/v1/audio/speech
Output streaming uses the same OpenAI-compatible speech endpoint. The request still contains the complete input text, but the client consumes audio before the complete response has downloaded.
Choose one wire format:
stream_format: "audio"streams raw bytes in the selected audio format and works with the official OpenAI SDK streaming helpers.stream_format: "sse"sends explicit KittenMLspeech.audio.deltaevents containing Base64 audio.
To send the input text incrementally as well, use the separate text-input WebSocket.
Binary and SSE output streaming share the HTTP endpoint's 40,000-character, 256 KiB JSON-body, and 30-minute request limits. For predictable latency, keep individual requests around 400–5,000 characters.
Stream binary audio with Python
import os
from openai import OpenAI
client = OpenAI(
api_key=os.environ["KITTENML_API_KEY"],
base_url="https://api.kittenml.com/v1",
)
with client.audio.speech.with_streaming_response.create(
model="kitten-tts-mini-0.8",
input="The first sentence can play while the next sentence is generated.",
voice="Bella",
response_format="mp3",
speed=1.0,
) as audio:
audio.stream_to_file("kitten-output.mp3")
stream_to_file writes bytes as they arrive instead of keeping the complete
audio response in application memory.
Stream binary audio with JavaScript
import {createWriteStream} from "node:fs";
import {Readable} from "node:stream";
import {pipeline} from "node:stream/promises";
import OpenAI from "openai";
const client = new OpenAI({
apiKey: process.env.KITTENML_API_KEY,
baseURL: "https://api.kittenml.com/v1",
});
const audio = await client.audio.speech.create({
model: "kitten-tts-mini-0.8",
input: "The first sentence can play while the next sentence is generated.",
voice: "Bella",
response_format: "mp3",
});
await pipeline(
Readable.fromWeb(audio.body),
createWriteStream("kitten-output.mp3"),
);
Stream SSE events
Set stream_format to sse when your application needs event boundaries:
curl --fail-with-body -sS -N \
https://api.kittenml.com/v1/audio/speech \
-H "Authorization: Bearer $KITTENML_API_KEY" \
-H "Content-Type: application/json" \
--data '{
"model": "kitten-tts-mini-0.8",
"input": "The first sentence can play while the next sentence is generated.",
"voice": "Bella",
"response_format": "mp3",
"stream_format": "sse"
}'
Each delta contains one Base64-encoded piece of the selected audio format:
data: {"type":"speech.audio.delta","audio":"SUQzBAAAAA..."}
data: {"type":"speech.audio.delta","audio":"qqqqqqqqqq..."}
data: {"type":"speech.audio.done","usage":{"input_tokens":0,"output_tokens":0,"total_tokens":0}}
Decode each audio value and concatenate the bytes in event order. The
combined bytes are one playable file; the server does not create a separate
file for each delta. speech.audio.done confirms that the stream completed.
Recover from interruption
If the connection closes before the HTTP response completes or before an SSE
speech.audio.done event, treat the audio as incomplete. Discard or explicitly
mark the partial output, then retry the generation as a new request. Do not
blindly append a retry to the partial file because encoded audio containers may
contain headers and trailers.
Runnable Python and JavaScript clients for both binary and SSE modes are in the output-streaming TTS examples.