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

> ## Agent Instructions
> Unmute compiles to exactly three targets. Pipecat and LiveKit are code targets: compile writes a Python project you run. SLNG is a hosted target: compile writes a deployment body and SLNG runs the agent, so it has no `unmute dev`. Those three are the only values `provider` accepts in `targets.yaml`. Deepgram and ElevenLabs appear in these docs as model vendors, which is not the same thing as a target, and `slng` is both.
> The Go structs in `internal/spec` and `internal/ir` are the schema truth. Check a field against them, or run `unmute validate`, rather than against what you remember.

# Text to speech

> The speak binding: every key it takes, the vendors each target can construct, and how one SLNG key reaches many voices.

`models.speak` picks the service that turns the agent's words into audio.

<Note>
  **SLNG is a host and a proxy, and one key covers both.** It runs its own
  copies of voice models, and it also forwards to the vendors' own endpoints.
  So a single `SLNG_API_KEY` reaches many vendors' voices, and you choose which
  of thirteen regions the audio is generated in. [One key, many
  voices](#one-key-many-voices) is the whole picture.
</Note>

On this page:

* [Quickstart](#quickstart) - the smallest binding that works
* [Every key a speak binding takes](#every-key-a-speak-binding-takes) - the full shape
* [One key, many voices](#one-key-many-voices) - hosted, proxied, and where it runs
* [Pipecat](#pipecat) and [LiveKit](#livekit) - the vendors each target can construct
* [Troubleshooting](#troubleshooting) - the refusals that come up most

## Quickstart

```yaml agent.yaml theme={null}
models:
  speak:
    voice:
      provider: slng
      model: "deepgram/aura:2"
      voice: "aura-2-thalia-en"
```

```sh theme={null}
unmute validate my-agent
```

This role usually takes a voice as well as a model. The entry's name, `voice`
here, is how the rest of the package refers to it; the `voice:` key inside it
is the vendor's voice id.

## Every key a speak binding takes

Which of `model:` and `voice:` are required depends on the vendor, and the
refusal names whichever one is missing.

<ParamField path="provider" type="string">
  A provider supported for this role and target, listed on the model pages. Required for
  an API binding; there is no inferred API provider. `local` selects local placement.
</ParamField>

<ParamField path="model" type="string">
  Provider model id, passed through as written. Required where the selected integration
  requires a model; otherwise its default applies. No model id is checked against a provider catalog.
</ParamField>

<ParamField path="voice" type="string">
  A voice id accepted by the selected model and provider. Unmute forwards it
  without checking a voice list. If omitted, the integration may choose its
  default or require a value. An unknown id can fail only when speech runs.
</ParamField>

<ParamField path="speed" type="number">
  Speaking speed on a `speak` entry. Provider-defined values and limits; omitted leaves
  the provider default.
</ParamField>

<ParamField path="language" type="string">
  A fixed BCP-47 language tag such as `es` or `en-US`, on `listen` or `speak`
  where the integration supports it. Accepted languages depend on the selected
  provider and model. Omission keeps that integration's default; it does not
  promise automatic detection. `{{language}}` is refused. Unmute exposes no
  tool or variable binding that changes this setting during a call.
</ParamField>

<ParamField path="placement" type="api | local">
  Whether the model is called over the network or runs in the agent's own
  process. Left out, it is `api` whenever the entry names a provider, a model
  or a voice. `local` is refused on the slng target, which has no machine of
  yours to run on.
</ParamField>

<ParamField path="endpoint_env" type="an environment variable name">
  Points at a variable holding an OpenAI-compatible endpoint URL. This is what
  lets a vendor that is not on Pipecat's list through. Pipecat only: LiveKit's
  OpenAI plugin carries no language slot for speech, so there is no custom
  endpoint for this role there, and the slng target has none either.
</ParamField>

<ParamField path="params" type="object">
  Provider parameter names and values. Omit to add no extra parameters. Provider limits
  apply; Unmute does not define a universal accepted set. SLNG `params.world_part`
  is checked against its supported regions.
</ParamField>

A `speak` entry cannot carry `fallback:`. That key is legal only on `think`
and `listen`; see [Reasoning model](/models/llm#fallback).

## One key, many voices

SLNG serves a voice model two ways, and the shape of the id says which:

| `model:`                  | What it means                                              |
| ------------------------- | ---------------------------------------------------------- |
| `slng/deepgram/aura:2-en` | a copy SLNG hosts itself                                   |
| `deepgram/aura:2`         | the vendor's own endpoint, reached through SLNG as a proxy |

Both are one binding and one `SLNG_API_KEY`. The point is that you do not
collect a key per vendor to reach a vendor's voice. The difference is who runs
the model and how it is billed, which
[docs.slng.ai](https://docs.slng.ai/execution-layer/byok) covers.

For **listening** the two differ in speed by enough to matter, and
[Speech to text](/models/stt#which-shape-to-pick-for-listening) explains the
gap. For speaking nobody has measured them against each other. The scaffold
takes the proxied route here to match the transcriber, not because it is known
to be faster.

### Where it runs

`params.world_part` picks the SLNG speech gateway that serves the call:

```yaml agent.yaml theme={null}
models:
  speak:
    voice:
      provider: slng
      model: "deepgram/aura:2"
      voice: "aura-2-thalia-en"
      params:
        world_part: eu-north
```

Thirteen are accepted: `us-east`, `us-west`, `br`, `eu-west`, `eu-north`,
`gb`, `za`, `il`, `jp`, `sg`, `id`, `au` and `in`. Left out, the SDK default
stands. A hosted `slng/` id is a separate question: those run only where SLNG
has put them, so a region you need may rule one out.
[Regional infrastructure](/optimization/regional-infrastructure) explains the
separate model, worker and media regions.

<Accordion title="The ids the scaffold and examples use">
  | Where                                                                                                                        | `model:`                  | `voice:`           |
  | ---------------------------------------------------------------------------------------------------------------------------- | ------------------------- | ------------------ |
  | `unmute init`, and every example, `hotel-concierge` on the `slng` target included                                            | `deepgram/aura:2`         | `aura-2-thalia-en` |
  | the SLNG-hosted English copy, which runs in `us-central` only, so an `slng` package deploying to `eu-central` cannot name it | `slng/deepgram/aura:2-en` | `aura-2-thalia-en` |

  These are the ids used by the scaffold and examples. The full SLNG catalog is at
  [docs.slng.ai/models](https://docs.slng.ai/models); any id from there goes in
  `model:` as written, for example `slng/cartesia/sonic-3` with a voice id of
  its own.
</Accordion>

## Pipecat

| Provider     | Notes                                                                                                                                 |
| ------------ | ------------------------------------------------------------------------------------------------------------------------------------- |
| `slng`       | SLNG hosted text to speech. `SLNG_API_KEY`.                                                                                           |
| `cartesia`   | Since Pipecat 1.9.0 the default model is `sonic-3.6`. Write `model: "sonic-3.5"` to stay on the previous one.                         |
| `deepgram`   | `params: {speed: 1.1}` sets Aura's speech rate, from 0.7 to 1.5.                                                                      |
| `elevenlabs` | also accepted as `eleven_labs`                                                                                                        |
| `gradium`    |                                                                                                                                       |
| `inworld`    |                                                                                                                                       |
| `openai`     |                                                                                                                                       |
| `rime`       |                                                                                                                                       |
| `sarvam`     | Since Pipecat 1.9.0 the default model is `bulbul:v3`. Sarvam's API no longer serves `bulbul:v2`, so a package naming it cannot speak. |
| `soniox`     | `params: {reduce_silence: true}` shortens the pauses between words, on models that support it.                                        |

An unlisted provider is legal on Pipecat on one condition: it has to be a
genuinely OpenAI-compatible endpoint, named with `endpoint_env`.

## LiveKit

| Provider     | Notes                                       |
| ------------ | ------------------------------------------- |
| `slng`       | SLNG hosted text to speech. `SLNG_API_KEY`. |
| `cartesia`   |                                             |
| `deepgram`   |                                             |
| `elevenlabs` | also accepted as `eleven_labs`              |
| `gemini`     |                                             |
| `gradium`    |                                             |
| `inworld`    |                                             |
| `rime`       |                                             |
| `sarvam`     |                                             |
| `soniox`     |                                             |

This list is closed, and closed harder than Pipecat's: LiveKit's OpenAI plugin
carries no language slot for speech, so there is no custom-endpoint fallback
for this role at all.

## The difference between the two

Pipecat has `openai`, LiveKit has `gemini`. Everything else matches.

## Troubleshooting

### The binding is missing a model, or missing a voice

The vendor needs both and the package gave one. **Fix:** add whichever the
message names. Which of the two a vendor needs is the vendor's own decision,
not a rule this page can shorten.

### `voice` is refused on a provider that clearly has voices

The vendor carries the voice inside the model id rather than in a separate
field, so the binding has no slot for it. **Fix:** drop `voice:` and name the
voice variant in `model:`.

### `fallback` is refused

A speak binding cannot have one, on any target. **Fix:** remove it. Fallback
is legal on `think` and `listen` only.

### `temperature`, `top_p` or `top_k` is refused

Those are think fields, which shape what the model writes rather than how it
is spoken. **Fix:** move them to the `think` binding, or delete them.

### `endpoint_env` is refused on LiveKit

LiveKit has no custom speech endpoint at all. **Fix:** bind a vendor from the
LiveKit list above, or compile to Pipecat, which emits the `endpoint_env`
lookup.

## Find a Soniox voice

Use the [SLNG Soniox voice catalog](https://docs.slng.ai/voices/soniox) to hear
voices and find their ids. Check the SLNG dashboard for voices available to
your selected model if the catalog differs. Copy the id exactly; do not infer an id from a
person's name or change its capitalization. For a direct Soniox binding, use
[Soniox's voice documentation](https://soniox.com/docs/tts/concepts/voices).

## Multilingual speech

The reply text and its spoken delivery are separate. A model can produce correct
Spanish text while TTS still uses an English language setting or voice accent.
Listen to each intended language before shipping a multilingual agent.

| TTS choice                  | Language behavior                                                                 | What to configure                                                                                  |
| --------------------------- | --------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------- |
| Soniox through SLNG         | The stream has a language setting; the SLNG catalog documents `en` as the default | Set `language` deliberately and select a voice suited to it. Omission is not a multilingual switch |
| ElevenLabs multilingual TTS | Can infer language from the text; model and voice still affect delivery           | Choose a multilingual model and suitable voice; a fixed language setting can constrain it          |

See [SLNG's Soniox catalog](https://docs.slng.ai/voices/soniox) and
[ElevenLabs language guidance](https://elevenlabs.io/docs/eleven-creative/playground/text-to-speech).
Provider support for runtime changes does not mean Unmute exposes those changes.

STT has its own language behavior. Do not assume that leaving `listen.language`
out enables detection for every provider. For example, Deepgram multilingual
recognition uses `language: multi`; see its
[LiveKit integration](https://docs.livekit.io/agents/models/stt/deepgram/).
Check the selected STT model separately from TTS.

For a Spanish-only agent, use a Spanish prompt and a speech binding configured
for Spanish. For a multilingual brief, choose TTS that handles the required
languages with the settings Unmute can emit. If that is not possible, explain
the tradeoff before reducing the agent to one language.

## Where to go next

<Columns cols={2}>
  <Card title="Reasoning model" icon="brain" href="/models/llm">
    The model that decides what to say.
  </Card>

  <Card title="SLNG Execution Layer" icon="zap" href="/optimization/execution-layer">
    The SLNG Execution Layer behind these models.
  </Card>

  <Card title="Regional infrastructure" icon="earth" href="/optimization/regional-infrastructure">
    Place speech compute and the agent worker separately.
  </Card>
</Columns>
