New AssemblyAI-TTS-1: Text-to-speech for voice agents. Learn more
Insights & Use Cases

Best ElevenLabs alternatives for AI phone agents (2026): what to switch to and what changes

A switching guide for phone agents leaving ElevenLabs: five alternatives compared on price, concurrency and μ-law output, plus what changes in your config and code for LiveKit, Pipecat and a raw Twilio loop.

Abstract green diamond illustration

Written by

Kelsey Foster

Published on

4 November 2026

Swapping a TTS provider in a phone agent sounds like a one-line change. Change the import, change the API key, ship it.

Then the first call goes out and the agent reads [laughs] out loud, because the new provider doesn't speak ElevenLabs audio tags. Or your μ-law stream turns to static because the new API takes the encoding as two parameters instead of one ulaw_8000 string. Or you discover that "concurrency" means something different on the other side.

This guide is for teams that have already decided to evaluate alternatives to ElevenLabs for phone and voice agents. It covers five alternatives built for real-time voice (AssemblyAI, Inworld, Cartesia, Deepgram, and Rime), then spends most of its time on the part other lists skip: what changes in your config and code when you switch, and how to do it in LiveKit, Pipecat, and a raw Twilio loop.

The alternatives at a glance

Prices as of October 28, 2026, from each vendor's own pricing page. Concurrency and telephony details from each vendor's docs on the same date.

Provider (model) List price How concurrency is limited 8 kHz μ-law Languages LiveKit / Pipecat
ElevenLabs v4 Turbo (what you're leaving) $0.04 per 1K characters Text to Dialogue WebSocket: one session per open connection, 14 (Free) to 105 (Scale, Business); rejected past the limit ulaw_8000 90+ Plugin only (retired from LiveKit Inference Aug 31, 2026) / Service
AssemblyAI (AssemblyAI-TTS-1) $15 per 1M characters New sessions per minute; open sessions aren't counted pcm_mulaw, pcm_alaw 6 Plugin and LiveKit Inference / AssemblyAITTSService in pipecat-ai 1.15.0+
Inworld (TTS-2, TTS-2 Flash) $25 / $15 per 1M characters (On-Demand) Concurrent generations by plan: 5 (On-Demand) to 500 (Growth) MULAW, ALAW 200+ languages and locales Plugin and LiveKit Inference / Service
Cartesia (Sonic 3.6) Credit plans from $5/mo (100K) to $299/mo (8M); about 1 credit per character Concurrent requests by plan: 2 (Free) to 15 (Scale); custom on Enterprise pcm_mulaw 44 Plugin and LiveKit Inference / Service
Deepgram (Flux TTS, Aura-2) Flux TTS $0.0450 per 1K characters Up to 45 concurrent streaming requests on Pay as You Go (North America) mulaw, alaw Not compared here Plugin and LiveKit Inference / Service
Rime (Mist v3, Coda v2) $0.030 / $0.050 per minute (Flex) Plan-based audio/x-mulaw Not compared here Plugin and LiveKit Inference / Service

Two columns deserve a second look. The concurrency column uses three different units (sessions, generations, and requests), so the numbers don't compare directly. And the pricing column mixes per-character and per-minute billing. Price a real month of your own call transcripts on each before you decide.

Why phone agents outgrow ElevenLabs

For phone agents, three things in ElevenLabs' own docs tend to start the conversation:

  • Session-based limits on the newest models. ElevenLabs' models documentation says Text to Dialogue WebSocket connections are metered as dialogue sessions. An open connection holds a session for as long as it stays open, whether or not audio is being generated, and a connection opened past the plan's limit is rejected with too_many_concurrent_requests. If your agent holds one socket per call, that limit is your concurrent call ceiling.
  • Idle connections close quickly. The same page says a dialogue connection closes after 20 seconds of inactivity unless you send keep-alive messages. Phone calls have long pauses while callers look things up.
  • LiveKit Inference no longer serves it. LiveKit's ElevenLabs plugin page says ElevenLabs was retired from LiveKit Inference on August 31, 2026. The plugin still works with your own ElevenLabs account.

None of that is a reason to switch on its own. If your agent needs 90+ languages or pronunciation dictionaries, those are real constraints on where you can go.

The alternatives, one by one

Each entry answers the same question: if you leave ElevenLabs for this provider, what do you gain and what do you give up?

AssemblyAI

AssemblyAI-TTS-1 is a text-to-speech model built for conversational voice agents, trained on millions of hours of audio, including real conversational data. It's frontier-level quality, faster than other production voice agent TTS models, and comes with thousands of voices and instant voice cloning in the dashboard.

What you gain: a concurrency model that counts call starts rather than open calls (more on that below), native pcm_mulaw and pcm_alaw at 8 kHz, US and EU data zones, $15 per 1M characters with no commitment, and the option to run speech-to-text, the LLM, and TTS on one API key with Universal-3.6 Pro Realtime and LLM Gateway.

What you give up: languages (six: English, Spanish, French, German, Italian, and Portuguese, with no automatic detection). Fine control too: the connection parameter docs say there's no speed, pitch, emotion, style, or stability parameter, and no pronunciation dictionary or SSML. Delivery is steered through the text itself, as the prompting guide describes.

How it benchmarks against ElevenLabs: in our evals from the launch post, AssemblyAI-TTS-1 scored 93.7% entity accuracy (phone numbers, dates, URLs, confirmation codes, drug names), level with ElevenLabs v4 at 93.6% and well ahead of ElevenLabs Flash v2.5 at 68.0%. On the independent Cekura leaderboard, it read phone numbers and codes correctly 92% of the time vs 89% for the best ElevenLabs model, and scored 4.50 on naturalness vs 4.42.

Inworld

TTS-2 and TTS-2 Flash cover 200+ languages and locales. Pricing is per character and drops on monthly plans.

What changes for a phone agent: concurrency is counted in generations. Inworld's concurrency docs list 5 concurrent generations on On-Demand and 500 on Growth, with WebSocket connections capped separately at 10 times the generation limit. Requests above the generation limit are best-effort.

Cartesia

Sonic 3.6 is generally available with 44 languages and outputs pcm_mulaw for telephony.

What changes for a phone agent: billing moves from characters to plan credits (about one credit per character), so a month's cost depends on which plan bucket you land in. Its pricing page caps TTS at 2 concurrent requests on Free, 3 on Pro, 5 on Startup, and 15 on Scale, with custom limits on Enterprise.

Deepgram

Flux TTS and Aura-2 stream over WebSocket and output mulaw or alaw at 8 kHz.

What changes for a phone agent: concurrency is a fixed number of simultaneous requests. Deepgram's rate-limit docs list up to 45 concurrent streaming TTS requests on Pay as You Go in North America, counted per project, and say extra projects on the same account don't add concurrency.

Rime

Mist v3 and Coda v2 are billed per minute of audio rather than per character, and Rime also licenses standalone engines for on-prem deployment.

What changes for a phone agent: its WebSocket v1 cancels a reply by context for barge-in. The legacy /ws binary endpoint can only interrupt by closing the connection, so pick v1 for a new build.

Hear AssemblyAI-TTS-1 on your own script

Paste a few lines your agent actually says and compare voices before you change any code.

Try playground

Is there a free ElevenLabs alternative?

Every provider here has a way to start without a contract. They aren't equivalent, so check what each one includes:

  • Rime lists a free plan with $50 of usage every month, no card required.
  • Inworld lists an On-Demand plan at $0 per month, pay as you go, with up to 70 minutes of TTS included.
  • Cartesia lists a free plan with 20K credits.
  • ElevenLabs has a free plan, and its dialogue session limit is lowest there (14 sessions).
  • AssemblyAI has a free plan; its TTS limits list 5 new sessions per minute on it, and you can sign up without a sales call. Check the pricing page for current free usage.

If "free" means open source and self-hosted, none of these five fit. That's a different trade: you run the GPUs and own the latency.

What changes when you switch

This is the checklist. Most migration bugs come from one of these rows.

What you configured in ElevenLabs What it becomes on AssemblyAI TTS Watch out for
voice_id from the ElevenLabs voice library voice_id (a UUID) from the AssemblyAI voice catalog, via Copy voice ID Voice IDs don't carry over. Pick a voice recorded in your agent's language
Cloned voice Re-create it in the AssemblyAI dashboard from a short reference recording The speaker must accept biometric consent terms; consent lasts 60 days unless renewed
model_id (eleven_v4_turbo, eleven_flash_v2_5) model assemblyai-tts-1 One model speaks all six languages
output_format ulaw_8000 encoding pcm_mulaw plus sample_rate 8000 Two parameters instead of one string. A-law is pcm_alaw
language_code language, as a full English name ("spanish") on the API or a code ("es") in the LiveKit plugin No detection: set it to the language your LLM writes
voice_settings (stability, similarity_boost, style, speed) No equivalent Steer delivery with punctuation, capitalization, and filler words in the text
Audio tags such as [laughs] Read aloud as words Strip tags from LLM output before sending
Pronunciation dictionaries No equivalent Write uncommon terms out; dash-separate acronyms (E-T-O) and digits (4-3-2-1)
Alignment data for interrupted replies Word boundaries (per-word timings) On by default on the raw WebSocket, off by default in the SDKs
xi-api-key header Authorization header with your AssemblyAI key Use temporary tokens for browser clients
Concurrency: requests or dialogue sessions per plan New sessions per minute, matching your streaming speech-to-text limit Reuse one session per call; don't open one per utterance
Idle close (20 s on dialogue sockets) Idle close after 2 minutes, adjustable with inactivity_timeout Send keep_alive during long caller pauses
Data residency on Enterprise workspaces EU data zone at tts.eu.assemblyai.com Cloned voices work only in the zone where you created them

The concurrency row is the one to model before you migrate. The TTS limits docs count new sessions per minute and never count sessions already open. A voice agent keeps one session for the whole call, so your limit is how many calls can start in a minute. With a limit of 100, for example, 100 calls can start in one minute and 110 in the next, and all 210 stay connected. That's how unlimited concurrency works in practice: capacity grows with your call volume and never requires negotiation.

Move your phone agent to one API key

Universal-3.6 Pro Realtime, LLM Gateway, and AssemblyAI TTS, with native 8 kHz μ-law and no commitment.

Sign up free

Switching inside LiveKit, Pipecat, and a Twilio loop

LiveKit

In LiveKit Agents, the swap is the tts= argument and an environment variable. Here's the ElevenLabs plugin as LiveKit's docs show it:

from livekit.agents import AgentSession
from livekit.plugins import elevenlabs

session = AgentSession(
    tts=elevenlabs.TTS(voice_id="ODq5zmih8GrVes37Dizd", model="eleven_multilingual_v2"),
    # ... llm, stt, etc.
)

And the AssemblyAI plugin, from the AssemblyAI LiveKit TTS docs:

from livekit.agents import AgentSession
from livekit.plugins import assemblyai

tts = assemblyai.TTS(
    model="assemblyai-tts-1",
    voice="49c443a4-8a1d-5f7e-b70b-98bdbd9823c3",  # Audrey
)
tts.prewarm()  # open the session before the first reply

session = AgentSession(
    tts=tts,
    # When the user interrupts, keep only the words they heard in the chat history
    use_tts_aligned_transcript=True,
    # ... llm, stt, etc.
)

Install livekit-plugins-assemblyai>=1.8.9, replace ELEVEN_API_KEY with ASSEMBLYAI_API_KEY in your .env, and add filter_markdown and filter_emoji to tts_text_transforms if your LLM produces them. If you'd rather keep billing in LiveKit Cloud, LiveKit's AssemblyAI TTS page shows the Inference route, assemblyai/assemblyai-tts-1, for library voices.

Pipecat

In Pipecat, the swap is one service in the pipeline. The ElevenLabs service, from Pipecat's docs:

import os

from pipecat.services.elevenlabs.tts import ElevenLabsTTSService

tts = ElevenLabsTTSService(
    api_key=os.getenv("ELEVENLABS_API_KEY"),
    settings=ElevenLabsTTSService.Settings(
        voice="21m00Tcm4TlvDq8ikWAM",
        model="eleven_flash_v2_5",
    ),
)

And the AssemblyAI service:

import os

from pipecat.services.assemblyai.tts import AssemblyAITTSService

tts = AssemblyAITTSService(
    api_key=os.environ["ASSEMBLYAI_API_KEY"],
    settings=AssemblyAITTSService.Settings(
        model="assemblyai-tts-1",
        voice="49c443a4-8a1d-5f7e-b70b-98bdbd9823c3",  # Audrey
    ),
)

AssemblyAI's AssemblyAITTSService shipped in pipecat-ai 1.15.0 (October 28, 2026). Install it with the assemblyai extra; the AssemblyAI Pipecat TTS docs have the full setup.

A raw Twilio loop

If you talk to Twilio Media Streams directly, the change is in the session config. With ElevenLabs you asked for ulaw_8000. With the AssemblyAI Python SDK, you set the encoding and rate separately, then forward each chunk as a base64 media message:

import base64
import json
import os

import assemblyai as aai

config = aai.TTSConfig(
    voice_id="49c443a4-8a1d-5f7e-b70b-98bdbd9823c3",  # Audrey
    language="english",
    encoding=aai.TTSEncoding.pcm_mulaw,  # was output_format="ulaw_8000"
    sample_rate=8000,
)


async def speak(twilio_ws, stream_sid, session, text):
    async for chunk in session.speak(text):
        await twilio_ws.send_text(json.dumps({
            "event": "media",
            "streamSid": stream_sid,
            "media": {"payload": base64.b64encode(chunk).decode()},
        }))


# One session per call, kept open for every turn:
# async with aai.AsyncTTSSession(config, api_key=os.environ["ASSEMBLYAI_API_KEY"]) as session:
#     await speak(twilio_ws, stream_sid, session, "Thanks for calling. How can I help?")

For barge-in, call session.cancel() and send Twilio a clear event. For streamed LLM output, use generate() per token and flush() at the end of the reply, as the quickstart shows. Our Twilio voice agent tutorial has the full server, including speech-to-text.

Test before you cut over

Run both providers side by side on a slice of real traffic before you flip the default. Score the things a caller notices: whether order numbers, prices, and names come through correctly at 8 kHz, how fast the first word arrives, and whether interruptions stop the agent cleanly. Our guide on how to evaluate TTS for voice agents has a scoring method, and AssemblyAI vs ElevenLabs for voice agents covers the platform-versus-speech-layer question if you're also reconsidering ElevenLabs for speech-to-text.

The real lesson from most migrations is that the voice was never the hard part. The hard part was every assumption the old provider baked into your code: tag syntax, encoding strings, idle timeouts, and what a "concurrent" request meant. Write those down as the checklist above, and the next switch is an afternoon instead of a sprint.

Start the switch today

Get an API key, set encoding to pcm_mulaw, and run your first call on AssemblyAI TTS.

Sign up free

Frequently Asked Questions (FAQs)

What is the best ElevenLabs alternative for AI phone agents?

It depends on what's pushing you off ElevenLabs. If concurrency and cost at volume are the problem and your calls are in English, Spanish, French, German, Italian, or Portuguese, AssemblyAI TTS counts call starts instead of open calls and costs $15 per 1M characters. If you need 90+ languages, look at Inworld's 200+ languages and locales.

Is there a free alternative to ElevenLabs for voice agents?

Yes, several providers let you start free. Rime lists $50 of usage a month with no card, Inworld's On-Demand plan includes up to 70 minutes of TTS, and Cartesia's free plan includes 20K credits. AssemblyAI has a free plan with 5 new TTS sessions per minute; check its pricing page for included usage.

What replaces ulaw_8000 when I switch from ElevenLabs to AssemblyAI?

Set two parameters instead of one string: encoding to pcm_mulaw and sample_rate to 8000. That produces raw 8 kHz μ-law with no header, which is what Twilio Media Streams expect. For A-law networks, use pcm_alaw. The model's native rate is 24 kHz, so 8 kHz output is resampled on the server.

Can I move my ElevenLabs cloned voice to another provider?

No, voice IDs and clones don't transfer between providers. Re-create the clone from a short reference recording in the new provider's dashboard. On AssemblyAI, the speaker must accept biometric consent terms, the clone works in the data zone where it was created, and consent lasts 60 days unless renewed.

Does AssemblyAI TTS support ElevenLabs audio tags or SSML?

No. AssemblyAI TTS has no SSML, audio tags, pronunciation dictionaries, or stability and speed settings. Bracketed tags like [laughs] are read aloud as words, so strip them before sending text. Steer delivery with punctuation, capitalization for stress, and filler words written into the text.

How does ElevenLabs API pricing compare to alternatives?

As of October 28, 2026, ElevenLabs lists v4 Turbo at $0.04 per 1K characters and v4 at $0.08 per 1K. AssemblyAI TTS is $15 per 1M characters, Inworld TTS-2 Flash is $15 per 1M On-Demand, and Rime bills per minute of audio. Price a month of your own transcripts, since units differ.