> ## Documentation Index
> Fetch the complete documentation index at: https://docs.getpatter.com/llms.txt
> Use this file to discover all available pages before exploring further.

# TTS

> Text-to-speech providers supported by Patter.

# TTS (Text-to-Speech)

TTS is used in **pipeline mode** to synthesize the agent's response audio. If you use an [engine](/python-sdk/engines) such as `OpenAIRealtime` or `ElevenLabsConvAI`, speech synthesis is handled internally by the engine.

Each TTS ships as both a **namespaced** class (`from getpatter.tts import elevenlabs` → `elevenlabs.TTS()`) and a **flat alias** (`from getpatter import ElevenLabsTTS`). They are equivalent — the flat aliases are convenient for short examples, the namespaced form avoids name collisions when mixing providers.

## Quickstart

```python theme={null}
import asyncio
from getpatter import Patter, Twilio, DeepgramSTT, ElevenLabsTTS

phone = Patter(carrier=Twilio(), phone_number="+15550001234")  # TWILIO_* from env

agent = phone.agent(
    stt=DeepgramSTT(),                            # DEEPGRAM_API_KEY from env
    tts=ElevenLabsTTS(voice_id="rachel"),         # ELEVENLABS_API_KEY from env
    system_prompt="You are a helpful assistant.",
)

async def main():
    await phone.serve(agent)

asyncio.run(main())
```

The same agent using namespaced imports:

```python theme={null}
from getpatter.stt import deepgram
from getpatter.tts import elevenlabs

agent = phone.agent(
    stt=deepgram.STT(),
    tts=elevenlabs.TTS(voice_id="rachel"),
    system_prompt="You are a helpful assistant.",
)
```

## Supported providers

| Flat import              | Namespaced import                 | Env var              | Install extra         |
| ------------------------ | --------------------------------- | -------------------- | --------------------- |
| `ElevenLabsTTS`          | `getpatter.tts.elevenlabs.TTS`    | `ELEVENLABS_API_KEY` | included              |
| `ElevenLabsWebSocketTTS` | `getpatter.tts.elevenlabs_ws.TTS` | `ELEVENLABS_API_KEY` | included              |
| `OpenAITTS`              | `getpatter.tts.openai.TTS`        | `OPENAI_API_KEY`     | included              |
| `CartesiaTTS`            | `getpatter.tts.cartesia.TTS`      | `CARTESIA_API_KEY`   | `getpatter[cartesia]` |
| `RimeTTS`                | `getpatter.tts.rime.TTS`          | `RIME_API_KEY`       | `getpatter[rime]`     |
| `LMNTTTS`                | `getpatter.tts.lmnt.TTS`          | `LMNT_API_KEY`       | `getpatter[lmnt]`     |
| `XaiTTS`                 | `getpatter.tts.xai.TTS`           | `XAI_API_KEY`        | `getpatter[xai]`      |

### Model / voice / format enums

Each provider exports typed `StrEnum`s for valid model IDs, voice presets, and output formats alongside the provider class. They keep `model=` / `voice=` / `output_format=` arguments tab-completable and reject typos at construction time, while still accepting raw strings for forward compatibility:

```python theme={null}
from getpatter.providers.openai_tts import OpenAITTSModel, OpenAITTSVoice
from getpatter.providers.elevenlabs_tts import ElevenLabsModel, ElevenLabsOutputFormat
from getpatter.providers.cartesia_tts import CartesiaTTSModel, CartesiaVoiceSpeed
from getpatter.providers.rime_tts import RimeModel, RimeAudioFormat
from getpatter.providers.lmnt_tts import LMNTModel, LMNTAudioFormat

tts = OpenAITTS(voice=OpenAITTSVoice.NOVA, model=OpenAITTSModel.GPT_4O_MINI_TTS)
```

## ElevenLabs

Streaming HTTP TTS via ElevenLabs. Default model `"eleven_flash_v2_5"` (\~75 ms TTFB, drop-in replacement for `eleven_turbo_v2_5`). Other valid `model_id` literals: `"eleven_v3"`, `"eleven_turbo_v2_5"`, `"eleven_multilingual_v2"`, `"eleven_monolingual_v1"`.

```python theme={null}
from getpatter import ElevenLabsTTS

tts = ElevenLabsTTS()                        # reads ELEVENLABS_API_KEY
tts = ElevenLabsTTS(voice_id="rachel")
tts = ElevenLabsTTS(api_key="...", voice_id="EXAVITQu4vr4xnSDxMaL", model_id="eleven_v3")
```

| Parameter       | Type                     | Default                           | Description                                                                                                                  |
| --------------- | ------------------------ | --------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
| `api_key`       | `str \| None`            | `None`                            | API key — reads from `ELEVENLABS_API_KEY` if omitted.                                                                        |
| `voice_id`      | `str`                    | `"21m00Tcm4TlvDq8ikWAM"` (Rachel) | ElevenLabs voice ID (or name).                                                                                               |
| `model_id`      | `ElevenLabsModel \| str` | `"eleven_flash_v2_5"`             | Typed literal: `eleven_flash_v2_5` / `eleven_turbo_v2_5` / `eleven_v3` / `eleven_multilingual_v2` / `eleven_monolingual_v1`. |
| `output_format` | `str`                    | `"pcm_16000"`                     | ElevenLabs output format.                                                                                                    |

### Telephony factories — `for_twilio()` / `for_telnyx()`

When ElevenLabs runs in pipeline mode behind a phone carrier you can negotiate the carrier-native codec at the ElevenLabs HTTP layer and skip per-chunk SDK-side transcoding. The factory variants do that for you:

```python theme={null}
from getpatter import ElevenLabsTTS

# Twilio Media Streams: μ-law @ 8 kHz native — no resample, no μ-law encode in Python.
tts = ElevenLabsTTS.for_twilio(voice_id="rachel")

# Telnyx default: PCM @ 16 kHz native — no resample.
tts = ElevenLabsTTS.for_telnyx(voice_id="rachel")
```

`CartesiaTTS.for_twilio()` / `for_telnyx()` and `ElevenLabsConvAI.for_twilio()` / `for_telnyx()` work the same way. Use them whenever you know the call will go out over Twilio or Telnyx — they shave tens of milliseconds off TTFB and drop CPU on long calls. **Plivo** pins mulaw 8 kHz in its answer XML, so the `.for_twilio()` factories apply unchanged.

### WebSocket variant

`ElevenLabsWebSocketTTS` is an opt-in low-latency drop-in for `ElevenLabsTTS` that uses the `/stream-input` WebSocket endpoint. It saves \~50 ms of HTTP request setup per utterance and avoids TLS cold-starts on bursty traffic. See the [ElevenLabs WebSocket setup page](/python-sdk/providers/elevenlabs-websocket) for full details.

```python theme={null}
from getpatter import ElevenLabsWebSocketTTS

tts = ElevenLabsWebSocketTTS()                       # reads ELEVENLABS_API_KEY
tts = ElevenLabsWebSocketTTS.for_twilio(api_key="...")   # ulaw_8000 native
tts = ElevenLabsWebSocketTTS.for_telnyx(api_key="...")   # pcm_16000 native
```

<Note>The WebSocket endpoint does not support `eleven_v3*` models — use the HTTP `ElevenLabsTTS` for v3.</Note>

## OpenAI

```python theme={null}
from getpatter import OpenAITTS

tts = OpenAITTS()                            # reads OPENAI_API_KEY
tts = OpenAITTS(voice="nova")

# Twilio: skip the intermediate 16 kHz step — resample 24k → 8k directly.
tts = OpenAITTS(target_sample_rate=8000)
```

| Parameter            | Type                    | Default                          | Description                                                                                                                                                           |
| -------------------- | ----------------------- | -------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `api_key`            | `str \| None`           | `None`                           | API key — reads from `OPENAI_API_KEY` if omitted.                                                                                                                     |
| `voice`              | `OpenAITTSVoice \| str` | `OpenAITTSVoice.ALLOY`           | One of `alloy`, `echo`, `fable`, `onyx`, `nova`, `shimmer`.                                                                                                           |
| `model`              | `OpenAITTSModel \| str` | `OpenAITTSModel.GPT_4O_MINI_TTS` | OpenAI TTS model ID. Older `tts-1` / `tts-1-hd` are accepted as raw strings.                                                                                          |
| `instructions`       | `str \| None`           | `None`                           | Voice direction (only honored by `gpt-4o-mini-tts` and newer).                                                                                                        |
| `speed`              | `float \| None`         | `None`                           | Playback speed multiplier in `[0.25, 4.0]`.                                                                                                                           |
| `target_sample_rate` | `int`                   | `16000`                          | Output sample rate. Must be `8000` or `16000`. Set to `8000` for Twilio carriers to collapse the 24 k→16 k→8 k chain into a single resample (\~1 ms saved per chunk). |

`OpenAITTSVoice` and `OpenAITTSModel` are exported alongside the provider class:

```python theme={null}
from getpatter.providers.openai_tts import OpenAITTSVoice, OpenAITTSModel
```

<Note>OpenAI TTS returns audio at 24 kHz — Patter automatically resamples to `target_sample_rate` (16 kHz by default; pass `target_sample_rate=8000` to deliver μ-law-ready PCM directly to Twilio).</Note>

## Cartesia

Raw PCM streaming via Cartesia's sonic-2 bytes endpoint. See [Cartesia setup](/python-sdk/providers/cartesia).

```python theme={null}
from getpatter import CartesiaTTS

tts = CartesiaTTS()                          # reads CARTESIA_API_KEY
tts = CartesiaTTS(voice="f786b574-daa5-4673-aa0c-cbe3e8534c02")  # Katie
```

## Rime

Arcana (high fidelity) and Mist (low latency) via Rime's HTTP endpoint. See [Rime setup](/python-sdk/providers/rime).

```python theme={null}
from getpatter import RimeTTS

tts = RimeTTS()                              # reads RIME_API_KEY
tts = RimeTTS(model="arcana", speaker="astra")
tts = RimeTTS(model="mistv2", speaker="cove", speed_alpha=1.1, reduce_latency=True)
```

## LMNT

Blizzard and Aurora via the LMNT HTTP API. See [LMNT setup](/python-sdk/providers/lmnt).

```python theme={null}
from getpatter import LMNTTTS

tts = LMNTTTS()                              # reads LMNT_API_KEY
tts = LMNTTTS(model="blizzard", voice="leah")
```

## xAI

Grok text-to-speech (default voice `eve`) with 26 built-in voices, inline speech tags, custom voice cloning, and telephony-native output. See [xAI TTS setup](/python-sdk/providers/xai-tts).

```python theme={null}
from getpatter import XaiTTS

tts = XaiTTS()                              # reads XAI_API_KEY
tts = XaiTTS(voice="leo", language="en")
tts = XaiTTS.for_twilio(voice="eve")        # μ-law @ 8 kHz native
```

## Missing credentials

Each class raises `ValueError` at construction time if no API key is resolved:

```
ValueError: ElevenLabs TTS requires an api_key. Pass api_key='...' or
set ELEVENLABS_API_KEY in the environment.
```

## What's Next

<CardGroup cols={2}>
  <Card title="STT" icon="microphone" href="/python-sdk/stt">Speech-to-text providers.</Card>
  <Card title="LLM" icon="brain" href="/python-sdk/llm">Language model providers.</Card>
</CardGroup>
