Pipecat
Overview
Pipecat ships Speechify TTS in its core package as SpeechifyHttpTTSService, first released in pipecat-ai 1.8.0. It is the TTS stage of a Pipecat pipeline: for each sentence the LLM writes, it calls POST /v1/audio/stream/with-timestamps, reads the Server-Sent Events stream, and pushes PCM audio frames and word timestamps downstream as they arrive.
Pipecat maintains the service. Its Speechify reference lists every argument.
Prerequisites
- Speechify API key (platform.speechify.ai/api-keys)
- Python 3.11 or later
- For the full agent: a Deepgram key for STT and an OpenAI key for the LLM (this guide’s stack, swap freely)
Install
pipecat-ai versions before 1.8.0 have no Speechify service. For the TTS smoke test alone, pip install "pipecat-ai[speechify]>=1.8.0" is enough.
Configure
Put credentials in .env:
The service does not read the environment itself. Pass the key as api_key=.
Create the service
Inside your bot’s async entry point:
Change any setting mid-conversation by queueing a TTSUpdateSettingsFrame(delta=SpeechifyHttpTTSService.Settings(...)).
Pair voice and model by language
simba-3.2 is English only and returns 400 for a non-English voice. Each voice’s models list in GET /v1/voices is the authority. Store voice and model together in config so a later swap cannot mismatch them.
Use simba-3.2 or simba-3.0 with this service. Older model ids are retired from API version 2026-09-21 and return 400 model_retired. See Models.
Word timestamps
Each speech.chunk event carries base64 PCM, the speech marks that became final with it, or both: marks lag their audio slightly, and the last chunk is often marks-only. Mark times are absolute milliseconds from the start of the request’s audio, not offsets into the chunk they arrive on. The service joins the marks into whole words and pushes each one as a TTSTextFrame whose presentation timestamp is the moment that word starts playing.
Pipecat uses those frames to record what the bot actually said. When the user interrupts, the assistant’s turn in the LLM context keeps only the words that were spoken, not the whole reply the LLM wrote.
Verify the TTS stage
This script runs a two-stage pipeline, the Speechify service and a processor that captures its output, so it needs only your Speechify key:
It writes speechify-pipecat.wav and prints the audio frames and word timestamps it received. Frame counts and times vary from run to run:
Run a full agent
bot.py wires Speechify into a Deepgram and OpenAI pipeline and serves it over Pipecat’s local WebRTC transport:
Pipeline order matters: transport.input() receives the user’s audio, Deepgram transcribes it, the user aggregator adds the transcript to the LLM context, the LLM writes the reply, Speechify speaks it, and transport.output() plays it back. The assistant aggregator sits last so it records only what reached the transport.
Run it and open http://localhost:7860 to talk to the agent in the browser:
The session lives inside async with aiohttp.ClientSession(), so it stays open for the whole conversation and closes when the runner ends.
Sample rate and your API version
The service requests audio at the pipeline’s output rate, 24 kHz unless your transport or PipelineParams(audio_out_sample_rate=...) sets another. It sends no Speechify-Version header, so your workspace’s pinned API version decides how the request is served.
On a workspace pinned before 2026-09-30, pcm_16000 returns 24 kHz audio, which a 16 kHz pipeline plays 1.5x slow and pitched down. If your pipeline runs at 16 kHz, move the pin to 2026-09-30 or later, or pass sample_rate=24000 to the service so the output transport resamples the audio. See the pcm_16000 changelog entry.
Troubleshooting
missing 1 required keyword-only argument: 'aiohttp_session'
missing 1 required keyword-only argument: 'aiohttp_session'
The service needs an aiohttp.ClientSession. Create one with async with aiohttp.ClientSession() as session: and pass it as aiohttp_session=session.
cannot import name 'SpeechifyTTSService' or no module pipecat.services.speechify
cannot import name 'SpeechifyTTSService' or no module pipecat.services.speechify
The class is SpeechifyHttpTTSService, and it first shipped in pipecat-ai 1.8.0. Upgrade with pip install -U "pipecat-ai[speechify]>=1.8.0".
Speechify API error with code not_found
Speechify API error with code not_found
base_url ends in /v1. Remove the argument; the default is https://api.speechify.ai.
400 when the bot speaks
400 when the bot speaks
The voice and model do not pair. simba-3.2 takes English voices only; use simba-3.0 with a voice in another language. The voice’s models list in GET /v1/voices names every model it pairs with.