Skip to main content

Overview

Pipecat is an open-source Python framework for building real-time voice agents. You compose your agent as a pipeline of services (speech-to-text, LLM, text-to-speech) that stream audio and data frames to each other, and Pipecat handles the orchestration, including turn-taking, interruptions, and transports such as WebRTC, Daily, and telephony. AssemblyAITTSService speaks your agent’s replies with the Streaming TTS API. Use it with AssemblyAISTTService and the LLM Gateway, and every model in the agent runs on one AssemblyAI API key.
AssemblyAITTSService is available in pipecat-ai 1.14.0+, with the assemblyai extra.
What the service handles for you:
  • Streaming by sentence. Each sentence of the LLM’s reply is its own request, so the agent starts speaking after the first sentence rather than after the whole reply.
  • One session per call. The service opens its WebSocket session when the pipeline starts and keeps it for every reply, sending a keepalive while the agent is quiet.
  • Barge-in without reconnecting. When the user interrupts, the service cancels the audio still in flight and keeps the session.
  • Word-timed context. Per-word timings drive Pipecat’s spoken-text frames, so an interrupted reply is saved to the LLM context only up to the word the user heard.

Quickstart

1

Install the packages

Install Pipecat with the AssemblyAI, OpenAI, and Silero extras, and the runner and WebRTC extras to talk to the agent in your browser. The OpenAI service connects the agent to the LLM Gateway, which speaks the OpenAI Chat Completions API.
2

Set your API key

Set your API key in a .env file:
You can get an AssemblyAI API key by signing up for a free account and going to the API Keys tab of the dashboard.
3

Build the agent

Save this as bot.py. It uses AssemblyAI for speech-to-text, the LLM, and text-to-speech:
4

Talk to it

Run the agent:
Open http://localhost:7860/client, allow the microphone, and press Connect. Use headphones, so the agent doesn’t hear its own voice. To run the agent in a Daily room or on a phone number, add their transports to transport_params; see Pipecat’s transports.
For the speech-to-text settings in this example, such as vad_force_turn_endpoint and mode, see Universal-3.6 Pro on Pipecat.

Reference agent

AssemblyAI voice agent starter for Pipecat

A starter agent that runs every model on AssemblyAI: Streaming TTS, Universal-3.6 Pro, and the LLM Gateway. Every model setting is a building block with a skill that teaches coding agents such as Claude Code when and how to tune it, from the voice to turn detection and noise suppression. It comes with tests and a Dockerfile for deploying to Pipecat Cloud. Fork it and make it yours.

Parameters reference

AssemblyAITTSService.Settings:

Choose a voice

Pass a voice to voice by its ID, a UUID. Unset, the session speaks with the server’s default voice, Jane (95e643fb-dd55-577f-80ec-134c3118efcc). voice takes any voice your account can use:
  • One of the AssemblyAI voices, which speak all six supported languages.
  • A voice from the AssemblyAI voice library. These speak one language, the language of their recording.
  • A voice you cloned in the AssemblyAI dashboard.
The Voice Library in the AssemblyAI dashboard has a Copy voice ID action for each voice; Voices also shows how to list voices from code. A slug such as aai-anna works too, but a voice’s ID never changes. A cloned voice works only on the host of the data zone it was created in.

Set the language

Set language to the language of the text your LLM writes:
language takes a Pipecat Language (Language.ES), a language code ("es", "es-MX"), or the language’s English name ("spanish"). The service sends the server the English name the API expects, so you can use the same Language values you pass to AssemblyAISTTService. See Languages for the six supported languages. Choose a voice that speaks the language. The AssemblyAI voices speak all six. A library or cloned voice speaks only the language it was recorded in: leave language unset and the session speaks the voice’s language. The API doesn’t detect language, so an AssemblyAI voice speaks English unless you set language.

Keep data in the EU

url sets the data zone. It defaults to the US, wss://tts.us.assemblyai.com/v1/ws. To keep text and audio in the EU, point the TTS at the EU host, and the STT and LLM Gateway at theirs:
The EU LLM Gateway serves a different set of models; see Cloud endpoints and data residency. For the TTS endpoints, see Endpoints and data zones.

Interruptions and context

When the user interrupts, the service sends Cancel on the open session and drops the audio of the interrupted reply that is still in flight. The session stays open, so the next reply doesn’t wait for a new handshake. The service always requests word boundaries and turns them into Pipecat’s spoken-text frames, timed to the audio. With no extra setting:
  • The assistant’s transcript follows the agent’s speech word by word.
  • When the user cuts the agent off, the assistant aggregator saves the reply to the LLM context only up to the word the user heard, so the LLM doesn’t think it said things it didn’t.

Latency

  • The session opens when the pipeline starts. The service connects during setup, so the first reply doesn’t wait on the handshake.
  • Greet with a TTSSpeakFrame. A fixed greeting queued in on_client_connected is spoken as soon as the user joins, without waiting for the LLM.
  • Keep replies short. The agent speaks after the first sentence, so a short first sentence starts the audio sooner. To start before a sentence is complete, set text_aggregation_mode=TextAggregationMode.TOKEN (from pipecat.services.tts_service).

Sessions and rate limits

AssemblyAI counts TTS sessions per account by new sessions per minute, not by sessions open at once. Because the service keeps one session for the whole call, a call usually opens one session.
  • Idle sessions. A session closes after two minutes with no frame either way, and an agent can be quiet that long while the user talks. The service sends a KeepAlive every 30 seconds to keep it open.
  • Long calls. A session lasts at most an hour. Between replies, the service replaces a session that is about to expire, so a reply is never cut off by the session’s end.
  • Errors. The service reconnects when the server marks an error as retryable, and waits as long as the server’s retry_after_seconds asks first. An error that can’t be retried before the session starts, such as an invalid API key or an unknown voice, marks the service unusable, so the pipeline’s ProcessorUnusablePolicy or a fallback service can act on it. See Error handling for the error codes.

Change the voice during a call

Push a TTSUpdateSettingsFrame to change the voice, language, or model:
The API fixes a session’s voice, language, and model when it opens, so the service reconnects with the new settings. Each new session counts toward your new sessions per minute.