Phase 3: Text-to-Speech (TTS) · 55 min · Python · ElevenLabs SDK · Cartesia SDK
ElevenLabs and Cartesia Integration
ElevenLabs for quality, Cartesia for speed — knowing when to use each is what separates senior voice AI engineers from juniors.
Hiring signal: TTS provider integration with TTFB measurement is a standard coding exercise in voice AI interviews at Vapi and Retell.
What you will learn
- Integrate ElevenLabs for high-quality TTS with voice selection and streaming
- Integrate Cartesia Sonic-3 for low-latency streaming TTS via WebSocket
- Measure and compare TTFB between ElevenLabs and Cartesia
- Choose between ElevenLabs and Cartesia based on use case requirements
The Problem
ElevenLabs and Cartesia are the two most-used TTS providers in production voice agents. They have different APIs, different streaming models, different pricing, and different strengths. You need to integrate both — ElevenLabs for premium experiences, Cartesia for latency-critical and cost-sensitive workloads.
The Concept
Provider Comparison
| Feature | ElevenLabs | Cartesia Sonic |
|---|
| Architecture | Autoregressive | Flow-Matching |
| TTFB | ~400ms | ~120ms |
| MOS | 4.5 | 4.2 |
| Price/min | $0.30 (Tier 1) | $0.015 |
| Voice cloning | Yes (instant + professional) | Yes (limited) |
| Streaming | WebSocket + HTTP chunked | WebSocket |
| Languages | 29 | 15 |
| Sample rates | 44.1kHz, 32kHz | 44.1kHz, 24kHz, 16kHz |
| Emotion control | Yes (via voice settings) | Yes (via context) |
| Speed control | Yes | Yes |
| API | REST + WebSocket | WebSocket |
ElevenLabs API
from elevenlabs import ElevenLabs
client = ElevenLabs(api_key=os.getenv("ELEVENLABS_API_KEY"))
# Streaming synthesis
audio_stream = client.text_to_speech.stream(
text="Hello, how can I help you today?",
voice_id="21m00Tcm4TlvDq8ikWAM",
model_id="eleven_turbo_v2_5",
voice_settings={"stability": 0.5, "similarity_boost": 0.75},
)
for chunk in audio_stream:
# chunk is raw audio bytes (MP3 or PCM)
yield chunk
Cartesia API
import websockets
import json
async def cartesia_stream(text, voice_id="c45a6b5a-9c3b-4c3b-8c3b-4c3b8c3b4c3b"):
url = "wss://api.cartesia.ai/tts/websocket"
headers = {"Authorization": f"Bearer {os.getenv('CARTESIA_API_KEY')}"}
async with websockets.connect(url, extra_headers=headers) as ws:
msg = {
"transcript": text,
"voice": {"id": voice_id},
"output_format": "pcm_16000",
"model": "sonic-2",
}
await ws.send(json.dumps(msg))
while True:
response = await ws.recv()
data = json.loads(response)
if data.get("type") == "chunk":
yield data["data"] # Audio bytes
elif data.get("type") == "done":
break
You're building a voice agent that needs both premium quality for VIP callers and low-latency for standard callers. How do you handle TTS provider selection?
Always use Cartesia for speed
Dual-Provider Routing
Unlock the full lesson
You've read the first 2 sections. The rest of this lesson covers Build It, Use It, Ship It, Evaluation, Key Terms, Common Pitfalls, Interview Framing — plus a hands-on lab, quiz, and project artifact.
Create a free account to unlock Phase 0 and Phase 1 of every course — no credit card.
Browse all courses · View pricing · DeVenture Academy