Streaming TTS in Python with Speechify
How to stream audio from the Speechify TTS API in Python with plain HTTP and requests. Covers chunked streaming to disk and piping audio to a player without waiting for the full payload.
The Node.js TTS post covers the same patterns in TypeScript. This post is the Python companion.
Why streaming matters
Python TTS is going to be mostly server-side. Batch jobs, content pipelines, document-to-audio converters. Waiting for the full payload before writing is fine when you’re generating a few seconds of audio at a time, but once you are synthesizing anything substantial, the length and payload size compounds. Now, the streaming endpoints take up to 20,000 spoken characters per request (SSML tags do not count; the non-streaming speech endpoint takes 2,000), which is huge. We’re not slow, but at that length non-streaming becomes a process block until the entire clip is generated and downloaded by your service.
Streaming starts to return audio data the moment it is generated, and you can write it to disk as quickly as it arrives. Time-to-first-byte can be dramatically quicker, memory pressure drops, and you can start playing or forwarding audio before synthesis is complete.
Install and setup
The API is plain HTTPS, so all you need is an HTTP client. This post uses requests, plus python-dotenv to load the key:
pip install requests python-dotenv
Or with uv:
uv add requests python-dotenv
Create a .env file with your key:
SPEECHIFY_API_KEY=your_key_here
Get a key from the Speechify console.
Streaming to disk with requests
POST /v1/audio/stream returns raw audio bytes as they are synthesized. Send the request with stream=True, iterate the body, and write each chunk to a file.
import os
import requests
from dotenv import load_dotenv
def main() -> None:
load_dotenv()
token = os.environ.get("SPEECHIFY_API_KEY")
if not token:
raise SystemExit("Set SPEECHIFY_API_KEY (copy .env.example to .env).")
with requests.post(
"https://api.speechify.ai/v1/audio/stream",
headers={
"Authorization": f"Bearer {token}",
"Content-Type": "application/json",
"Accept": "audio/mpeg",
},
json={
"input": (
"Streaming lets you start playing audio before the whole clip is ready. "
"This sentence is being synthesized and written to disk chunk by chunk."
),
"voice_id": "geffen_32",
"model": "simba-3.2",
},
stream=True,
timeout=60,
) as resp:
resp.raise_for_status()
out_file = "output.mp3"
with open(out_file, "wb") as f:
for chunk in resp.iter_content(chunk_size=8192):
if chunk:
f.write(chunk)
print(f"Streamed audio to {out_file}")
if __name__ == "__main__":
main()
stream=True on the requests.post call tells requests not to buffer the response body. iter_content(chunk_size=8192) gives you 8 KB chunks as they arrive. The if chunk guard skips keepalive bytes. The Accept header picks the container: audio/mpeg, audio/ogg, audio/aac, or audio/pcm (returns audio/L16, 24 kHz mono).
Pipe to ffplay for live playback
During development you often just want to hear the output immediately without writing a file. Pipe the stream directly to ffplay:
import os
import subprocess
import requests
from dotenv import load_dotenv
def main() -> None:
load_dotenv()
token = os.environ.get("SPEECHIFY_API_KEY")
if not token:
raise SystemExit("Set SPEECHIFY_API_KEY")
player = subprocess.Popen(
["ffplay", "-nodisp", "-autoexit", "-i", "pipe:0"],
stdin=subprocess.PIPE,
stderr=subprocess.DEVNULL,
)
try:
with requests.post(
"https://api.speechify.ai/v1/audio/stream",
headers={
"Authorization": f"Bearer {token}",
"Content-Type": "application/json",
"Accept": "audio/mpeg",
},
json={"input": "Hello from the pipe.", "voice_id": "geffen_32", "model": "simba-3.2"},
stream=True,
timeout=60,
) as resp:
resp.raise_for_status()
for chunk in resp.iter_content(chunk_size=8192):
if chunk:
player.stdin.write(chunk)
finally:
player.stdin.close()
player.wait()
if __name__ == "__main__":
main()
ffplay reads from pipe:0 (stdin), starts playing as soon as it has enough data to decode the first frame, and exits when the stream closes. You need ffmpeg installed (brew install ffmpeg or apt install ffmpeg). This is a development tool, not a production pattern.
What’s next
The Speechify TTS docs cover the full parameter surface: voice selection, SSML, and word-level timestamps.
This post is narrated by Harper on Simba 3.2 through our text to speech API. How the player works: add read-aloud to your docs and turn speech marks into captions.