# Quickstart

> Sign up, store your provider key, and hear a sentence through the router: once from the provider, then from the cache.

You need an API key from one of the providers, Python 3.10 or later, and, for step 4, a LiveKit agent on `livekit-agents` 1.8.5 or later. Step 5 works without an agent.

## 1. Sign up

Create your account at [ttscacherouter.dev](https://ttscacherouter.dev/signup).

Signing up creates your **org**, which owns your API keys, provider keys, cache and usage, and an API key for it. The next two steps happen on the [dashboard](https://app.ttscacherouter.dev/app)’s home.

## 2. Add your provider key

Pick the provider your agent uses and add your key for it.

The router calls the provider with this key, so the provider bills you directly for the sentences it synthesizes. The key is stored encrypted and never shown again; your agent never sends it.

## 3. Copy your API key

Your agent authenticates to the router with this key alone.

Copy it from the top of the dashboard. It starts with `tcr_`. Set it in your agent’s environment:

```shell
export TTS_CACHE_ROUTER_API_KEY=tcr_…
```

## 4. Connect your agent

Install our LiveKit plugin and make it your agent's TTS.

```shell
pip install livekit-plugins-tts-cache-router
```

**Sarvam**

```python
from livekit.plugins import tts_cache_router as tcr

# The API key comes from TTS_CACHE_ROUTER_API_KEY.
tts = tcr.TTS(
    model="sarvam/bulbul:v3",
    voice="shubh",
    language="hi-IN",
)

# then, in your entrypoint:
# session = AgentSession(vad=..., stt=..., llm=..., tts=tts)
```

**Raya**

```python
from livekit.plugins import tts_cache_router as tcr

# The API key comes from TTS_CACHE_ROUTER_API_KEY.
tts = tcr.TTS(
    model="raya/standard",
    voice="d6a002d0-230c-49b1-a137-b8a7d564b1ae",
    language="hi",
)

# then, in your entrypoint:
# session = AgentSession(vad=..., stt=..., llm=..., tts=tts)
```

**ElevenLabs**

```python
from livekit.plugins import tts_cache_router as tcr

# The API key comes from TTS_CACHE_ROUTER_API_KEY.
tts = tcr.TTS(
    model="elevenlabs/eleven_flash_v2_5",
    voice="JBFqnCBsd6RMkjVDRZzb",
)

# then, in your entrypoint:
# session = AgentSession(vad=..., stt=..., llm=..., tts=tts)
```

**OpenAI**

```python
from livekit.plugins import tts_cache_router as tcr

# The API key comes from TTS_CACHE_ROUTER_API_KEY.
tts = tcr.TTS(
    model="openai/gpt-4o-mini-tts",
    voice="ash",
)

# then, in your entrypoint:
# session = AgentSession(vad=..., stt=..., llm=..., tts=tts)
```

**Deepgram**

```python
from livekit.plugins import tts_cache_router as tcr

# The API key comes from TTS_CACHE_ROUTER_API_KEY.
tts = tcr.TTS(
    model="deepgram/aura-2",
    voice="thalia-en",
)

# then, in your entrypoint:
# session = AgentSession(vad=..., stt=..., llm=..., tts=tts)
```

**xAI**

```python
from livekit.plugins import tts_cache_router as tcr

# The API key comes from TTS_CACHE_ROUTER_API_KEY.
tts = tcr.TTS(
    model="xai/xai-tts",
    voice="ara",
    language="auto",
)

# then, in your entrypoint:
# session = AgentSession(vad=..., stt=..., llm=..., tts=tts)
```

**Soniox**

```python
from livekit.plugins import tts_cache_router as tcr

# The API key comes from TTS_CACHE_ROUTER_API_KEY.
tts = tcr.TTS(
    model="soniox/tts-rt-v2",
    voice="Adrian",
    language="en",
)

# then, in your entrypoint:
# session = AgentSession(vad=..., stt=..., llm=..., tts=tts)
```

**Smallest AI**

```python
from livekit.plugins import tts_cache_router as tcr

# The API key comes from TTS_CACHE_ROUTER_API_KEY.
tts = tcr.TTS(
    model="smallestai/lightning_v3.1_pro",
    voice="meher",
    language="en",
)

# then, in your entrypoint:
# session = AgentSession(vad=..., stt=..., llm=..., tts=tts)
```

**Cartesia**

```python
from livekit.plugins import tts_cache_router as tcr

# The API key comes from TTS_CACHE_ROUTER_API_KEY.
tts = tcr.TTS(
    model="cartesia/sonic-3",
    voice="f786b574-daa5-4673-aa0c-cbe3e8534c02",
    language="en",
)

# then, in your entrypoint:
# session = AgentSession(vad=..., stt=..., llm=..., tts=tts)
```

**Gemini**

```python
from livekit.plugins import tts_cache_router as tcr

# The API key comes from TTS_CACHE_ROUTER_API_KEY.
tts = tcr.TTS(
    model="gemini/gemini-3.8-flash-tts",
    voice="Kore",
)

# then, in your entrypoint:
# session = AgentSession(vad=..., stt=..., llm=..., tts=tts)
```

The settings use the same names for every provider: `model` as `<provider>/<model>`, `voice`, `language`, `speed` and the provider’s `options`. Every option is on the provider’s page: [Sarvam](https://docs.ttscacherouter.dev/livekit/sarvam.md), [Raya](https://docs.ttscacherouter.dev/livekit/raya.md), [ElevenLabs](https://docs.ttscacherouter.dev/livekit/elevenlabs.md), [OpenAI](https://docs.ttscacherouter.dev/livekit/openai.md), [Deepgram](https://docs.ttscacherouter.dev/livekit/deepgram.md), [xAI](https://docs.ttscacherouter.dev/livekit/xai.md), [Soniox](https://docs.ttscacherouter.dev/livekit/soniox.md), [Smallest AI](https://docs.ttscacherouter.dev/livekit/smallestai.md), [Cartesia](https://docs.ttscacherouter.dev/livekit/cartesia.md), [Gemini](https://docs.ttscacherouter.dev/livekit/gemini.md). Each page also shows how to keep the provider’s own LiveKit plugin and change only its URL and key.

> Building with Pipecat? `pip install pipecat-tts-cache-router` and put [TTSCacheRouterTTSService](https://docs.ttscacherouter.dev/pipecat.md) in your pipeline instead.

## 5. Hear it, twice

Run your agent and talk to it, or speak one sentence with this script.

**Sarvam**

```python
import asyncio

import aiohttp
from livekit import rtc
from livekit.plugins import tts_cache_router as tcr


async def main() -> None:
    async with aiohttp.ClientSession() as http:
        tts = tcr.TTS(
            model="sarvam/bulbul:v3",
            voice="shubh",
            language="hi-IN",
            http_session=http,
        )
        tts.on("metrics_collected", lambda m: print(f"characters billed by the provider: {m.characters_count}"))
        frames = [event.frame async for event in tts.synthesize("धन्यवाद, आपकी चार लोगों की टेबल आज रात आठ बजे के लिए बुक है।")]
        with open("hello.wav", "wb") as f:
            f.write(rtc.combine_audio_frames(frames).to_wav_bytes())
        await tts.aclose()


asyncio.run(main())
```

**Raya**

```python
import asyncio

import aiohttp
from livekit import rtc
from livekit.plugins import tts_cache_router as tcr


async def main() -> None:
    async with aiohttp.ClientSession() as http:
        tts = tcr.TTS(
            model="raya/standard",
            voice="d6a002d0-230c-49b1-a137-b8a7d564b1ae",
            language="hi",
            http_session=http,
        )
        tts.on("metrics_collected", lambda m: print(f"characters billed by the provider: {m.characters_count}"))
        frames = [event.frame async for event in tts.synthesize("धन्यवाद, आपकी चार लोगों की टेबल आज रात आठ बजे के लिए बुक है।")]
        with open("hello.wav", "wb") as f:
            f.write(rtc.combine_audio_frames(frames).to_wav_bytes())
        await tts.aclose()


asyncio.run(main())
```

**ElevenLabs**

```python
import asyncio

import aiohttp
from livekit import rtc
from livekit.plugins import tts_cache_router as tcr


async def main() -> None:
    async with aiohttp.ClientSession() as http:
        tts = tcr.TTS(
            model="elevenlabs/eleven_flash_v2_5",
            voice="JBFqnCBsd6RMkjVDRZzb",
            http_session=http,
        )
        tts.on("metrics_collected", lambda m: print(f"characters billed by the provider: {m.characters_count}"))
        frames = [event.frame async for event in tts.synthesize("Thanks for calling. Your table for four is booked for eight tonight.")]
        with open("hello.wav", "wb") as f:
            f.write(rtc.combine_audio_frames(frames).to_wav_bytes())
        await tts.aclose()


asyncio.run(main())
```

**OpenAI**

```python
import asyncio

import aiohttp
from livekit import rtc
from livekit.plugins import tts_cache_router as tcr


async def main() -> None:
    async with aiohttp.ClientSession() as http:
        tts = tcr.TTS(
            model="openai/gpt-4o-mini-tts",
            voice="ash",
            http_session=http,
        )
        tts.on("metrics_collected", lambda m: print(f"characters billed by the provider: {m.characters_count}"))
        frames = [event.frame async for event in tts.synthesize("Thanks for calling. Your table for four is booked for eight tonight.")]
        with open("hello.wav", "wb") as f:
            f.write(rtc.combine_audio_frames(frames).to_wav_bytes())
        await tts.aclose()


asyncio.run(main())
```

**Deepgram**

```python
import asyncio

import aiohttp
from livekit import rtc
from livekit.plugins import tts_cache_router as tcr


async def main() -> None:
    async with aiohttp.ClientSession() as http:
        tts = tcr.TTS(
            model="deepgram/aura-2",
            voice="thalia-en",
            http_session=http,
        )
        tts.on("metrics_collected", lambda m: print(f"characters billed by the provider: {m.characters_count}"))
        frames = [event.frame async for event in tts.synthesize("Thanks for calling. Your table for four is booked for eight tonight.")]
        with open("hello.wav", "wb") as f:
            f.write(rtc.combine_audio_frames(frames).to_wav_bytes())
        await tts.aclose()


asyncio.run(main())
```

**xAI**

```python
import asyncio

import aiohttp
from livekit import rtc
from livekit.plugins import tts_cache_router as tcr


async def main() -> None:
    async with aiohttp.ClientSession() as http:
        tts = tcr.TTS(
            model="xai/xai-tts",
            voice="ara",
            language="auto",
            http_session=http,
        )
        tts.on("metrics_collected", lambda m: print(f"characters billed by the provider: {m.characters_count}"))
        frames = [event.frame async for event in tts.synthesize("Thanks for calling. Your table for four is booked for eight tonight.")]
        with open("hello.wav", "wb") as f:
            f.write(rtc.combine_audio_frames(frames).to_wav_bytes())
        await tts.aclose()


asyncio.run(main())
```

**Soniox**

```python
import asyncio

import aiohttp
from livekit import rtc
from livekit.plugins import tts_cache_router as tcr


async def main() -> None:
    async with aiohttp.ClientSession() as http:
        tts = tcr.TTS(
            model="soniox/tts-rt-v2",
            voice="Adrian",
            language="en",
            http_session=http,
        )
        tts.on("metrics_collected", lambda m: print(f"characters billed by the provider: {m.characters_count}"))
        frames = [event.frame async for event in tts.synthesize("Thanks for calling. Your table for four is booked for eight tonight.")]
        with open("hello.wav", "wb") as f:
            f.write(rtc.combine_audio_frames(frames).to_wav_bytes())
        await tts.aclose()


asyncio.run(main())
```

**Smallest AI**

```python
import asyncio

import aiohttp
from livekit import rtc
from livekit.plugins import tts_cache_router as tcr


async def main() -> None:
    async with aiohttp.ClientSession() as http:
        tts = tcr.TTS(
            model="smallestai/lightning_v3.1_pro",
            voice="meher",
            language="en",
            http_session=http,
        )
        tts.on("metrics_collected", lambda m: print(f"characters billed by the provider: {m.characters_count}"))
        frames = [event.frame async for event in tts.synthesize("Thanks for calling. Your table for four is booked for eight tonight.")]
        with open("hello.wav", "wb") as f:
            f.write(rtc.combine_audio_frames(frames).to_wav_bytes())
        await tts.aclose()


asyncio.run(main())
```

**Cartesia**

```python
import asyncio

import aiohttp
from livekit import rtc
from livekit.plugins import tts_cache_router as tcr


async def main() -> None:
    async with aiohttp.ClientSession() as http:
        tts = tcr.TTS(
            model="cartesia/sonic-3",
            voice="f786b574-daa5-4673-aa0c-cbe3e8534c02",
            language="en",
            http_session=http,
        )
        tts.on("metrics_collected", lambda m: print(f"characters billed by the provider: {m.characters_count}"))
        frames = [event.frame async for event in tts.synthesize("Thanks for calling. Your table for four is booked for eight tonight.")]
        with open("hello.wav", "wb") as f:
            f.write(rtc.combine_audio_frames(frames).to_wav_bytes())
        await tts.aclose()


asyncio.run(main())
```

**Gemini**

```python
import asyncio

import aiohttp
from livekit import rtc
from livekit.plugins import tts_cache_router as tcr


async def main() -> None:
    async with aiohttp.ClientSession() as http:
        tts = tcr.TTS(
            model="gemini/gemini-3.8-flash-tts",
            voice="Kore",
            http_session=http,
        )
        tts.on("metrics_collected", lambda m: print(f"characters billed by the provider: {m.characters_count}"))
        frames = [event.frame async for event in tts.synthesize("Thanks for calling. Your table for four is booked for eight tonight.")]
        with open("hello.wav", "wb") as f:
            f.write(rtc.combine_audio_frames(frames).to_wav_bytes())
        await tts.aclose()


asyncio.run(main())
```

Run it twice. The first run synthesizes the sentence at the provider, which bills its characters (60 for the Hindi sentence, 68 for the English one), and caches it. The second plays it from the cache and bills nothing. Both write the same audio to `hello.wav`.

```shell
$ python hello.py
characters billed by the provider: 60
$ python hello.py
characters billed by the provider: 0
```

> In an agent, the same happens per sentence: the first time your agent says something it comes from the provider, every time after from the cache. The plugin’s `TTSMetrics` count only the characters the provider billed.

## 6. See what it saved

The dashboard's Usage page counts sentences served from the cache against those the provider synthesized.

Open [Usage](https://app.ttscacherouter.dev/app/usage) for the hit rate and the characters kept off your provider’s bill, per hour or day and per provider. Counts arrive within about a minute.

Next: [how the cache works](https://docs.ttscacherouter.dev/index.md), or every setting of the [LiveKit plugin](https://docs.ttscacherouter.dev/livekit.md).
