Skip to navigation

LiveKit

Add Speechify TTS to a LiveKit AgentSession in Python or Node.js with LiveKit's official plugins.

Overview

LiveKit Agents supports Speechify TTS in both of its frameworks, through plugins LiveKit publishes. You construct speechify.TTS(...) and pass it as the tts of your AgentSession, alongside your STT and LLM providers.

FrameworkPackageUse this version or later
Python (livekit-agents)livekit-plugins-speechify1.8.6, released 9 Oct 2026
Node.js (@livekit/agents)@livekit/agents-plugin-speechify1.9.2, released 9 Oct 2026

Both plugins stream. Each sentence of the agent’s reply is one request to POST /v1/audio/stream/with-timestamps, and the plugin forwards audio (24 kHz mono PCM) and word timestamps as they arrive. Requests share one keep-alive connection, and prewarm() opens it before the first reply; AgentSession calls prewarm() for you when the agent starts. Python 1.8.6 is the first release with connection reuse, prewarm() and a streamed synthesize(), so pin at least that version.

Prerequisites

  • Speechify API key (platform.speechify.ai/api-keys)
  • LiveKit project (URL, API key, and secret)
  • Deepgram key for STT, OpenAI key for LLM (this guide’s stack; swap freely)

Install

python3 -m venv .venv
source .venv/bin/activate
pip install "livekit-agents[codecs]>=1.8.6" \
"livekit-plugins-speechify>=1.8.6" \
"livekit-plugins-deepgram>=1.8.6" \
"livekit-plugins-openai>=1.8.6" \
python-dotenv

Configure

Put credentials in .env:

SPEECHIFY_API_KEY=your_speechify_api_key
LIVEKIT_URL=wss://your-project.livekit.cloud
LIVEKIT_API_KEY=your_livekit_api_key
LIVEKIT_API_SECRET=your_livekit_api_secret
DEEPGRAM_API_KEY=your_deepgram_api_key
OPENAI_API_KEY=your_openai_api_key

Both plugins read SPEECHIFY_API_KEY when you don’t pass a key to speechify.TTS(...) yourself (api_key= in Python, apiKey in Node.js). Keep it in the agent process, never in a browser participant.

Wire Speechify into AgentSession

from dotenv import load_dotenv
from livekit import agents
from livekit.agents import Agent, AgentServer, AgentSession
from livekit.plugins import deepgram, openai, speechify
load_dotenv()
class Assistant(Agent):
def __init__(self) -> None:
super().__init__(
instructions=(
"You are a helpful voice assistant speaking with a Speechify voice. "
"Keep replies short, clear, and conversational."
)
)
server = AgentServer()
@server.rtc_session(agent_name="speechify-tts-demo")
async def entrypoint(ctx: agents.JobContext) -> None:
session = AgentSession(
stt=deepgram.STT(model="nova-3"),
llm=openai.LLM(model="gpt-4o-mini"),
tts=speechify.TTS(voice_id="dominic_32", model="simba-3.2"),
)
await session.start(room=ctx.room, agent=Assistant())
await session.generate_reply(
instructions="Greet the user and mention that your voice is powered by Speechify TTS."
)
if __name__ == "__main__":
agents.cli.run_app(server)

Save it as agent.py.

The speechify.TTS(...) line is the whole integration. Both plugins default to dominic_32 on simba-3.2. Pair voice_id (voiceId in Node.js) and model by language, not by voice family - the *_32 voices run on simba-3.0 too. simba-3.2 is English only, so pass it any English voice; use simba-3.0 for every other language. Each voice’s models list in GET /v1/voices is the authority. See Models for the compatibility matrix.

Verify without a LiveKit room

The plugin’s synthesize(...) method calls Speechify directly and streams the audio back, so you can prove the TTS path works before provisioning a room. Set SPEECHIFY_API_KEY in the environment first.

import asyncio
import wave
from livekit.plugins import speechify
async def main() -> None:
tts = speechify.TTS(voice_id="dominic_32", model="simba-3.2")
tts.prewarm()
frames = []
async with tts.synthesize("Hello from Speechify TTS on LiveKit.") as stream:
async for event in stream:
frames.append(event.frame)
await tts.aclose()
with wave.open("speechify-tts-smoke.wav", "wb") as wf:
wf.setnchannels(1)
wf.setsampwidth(2)
wf.setframerate(24000)
for frame in frames:
wf.writeframes(frame.data)
asyncio.run(main())

A successful run writes speechify-tts-smoke.wav, about 4 seconds at 24 kHz mono.

Run the full agent

Once the smoke test passes, run against a LiveKit room:

# Local terminal (microphone + speakers, no room)
python agent.py console
# Development LiveKit project
python agent.py dev
# Production
python agent.py start

Troubleshooting

If Python cannot verify TLS certificates when calling Speechify, point SSL_CERT_FILE at your system bundle or the certifi bundle before running:

export SSL_CERT_FILE=/etc/ssl/cert.pem

The plugins only read the env var when you construct speechify.TTS() without a key. If you pass api_key= (Python) or apiKey (Node.js), it takes precedence; omit it to use the env var.

The agents CLI sets up logging for you. A standalone script that uses the plugin outside cli.runApp must call initializeLogger({ pretty: false, level: 'warn' }) from @livekit/agents first, as the smoke test above does.

Resources