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.
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?
A dual-provider setup lets you optimize for both quality and cost. VIP callers get ElevenLabs' 4.5 MOS with voice cloning — the 400ms TTFB is acceptable for premium service. Standard callers get Cartesia's 120ms TTFB at $0.015/min — 20x cheaper than ElevenLabs. The routing logic can be based on caller tier (from CRM), A/B testing, or even dynamic: use Cartesia during high-volume hours and ElevenLabs during low-volume hours.
Dual-Provider Routing
Unlock the full lesson
You've read the first 2 sections. The rest of this lesson covers Build, Check Yourself, Key Terms & Next — plus a hands-on lab, quiz, and project artifact.
Create a free account — the opening phases of 29 of 35 courses are free, no credit card.
Browse all courses · View pricing · DeVenture Academy