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

# LiveKit integration

> Use Coda WebSocket v1 as the speech for a LiveKit agent with the Rime plugin. The guide also covers plugin parameters, the stream lifecycle, and moving from /ws3.

Set `websocket_url="wss://coda.api.rime.ai/ws"` and `model="coda"` in `rime.TTS` to use Coda WebSocket v1. The plugin handles authorization, message encoding, sentence buffering, audio decoding, and connection reuse.

## Install the plugin

Use Python 3.11 or later, [uv](https://docs.astral.sh/uv/getting-started/installation/), and `livekit-plugins-rime` version `1.8.2` or later. [LiveKit Agents 1.8.2](https://github.com/livekit/agents/releases/tag/livekit-agents%401.8.2) introduced Coda WebSocket v1 support for both JSON and binary protocols, and earlier plugin versions do not accept `websocket_url` or `websocket_protocol`. Set `RIME_API_KEY` in your server's environment, because the plugin sends this key to the selected endpoint.

These commands create a project and install the LiveKit Rime plugin:

```bash theme={null}
uv init --python 3.11 coda-livekit
cd coda-livekit
uv add 'livekit-plugins-rime>=1.8.2'
```

For an existing project, run the same `uv add` command in its directory to update the dependency requirement. The plugin installs compatible `livekit-agents` and `rime-api` dependencies. Commit your `uv.lock` file so deployments use the same dependencies.

## Use the plugin in an agent session

Pass `rime.TTS` to your `AgentSession`. This example assumes that the agent already supplies speech recognition and an LLM. Set `model="coda"`, because the plugin reads the model from a `/{model}/ws` path, and the path on `coda.api.rime.ai` is only `/ws`. Without `model`, the plugin raises `ValueError`.

```python theme={null}
from livekit.agents import AgentSession
from livekit.plugins import rime

session = AgentSession(
    tts=rime.TTS(
        websocket_url="wss://coda.api.rime.ai/ws",
        model="coda",
        websocket_protocol="binary",
        speaker="lyra",
        lang="en",
    ),
)
```

Keep these points in mind:

* **Encoding:** the plugin defaults to binary. Set `websocket_protocol="json"` to use JSON. Both modes support streaming through `session.say()` and streamed LLM replies, so do not add a `tts.StreamAdapter`.
* **Agent setup:** for room setup, speech recognition, and an LLM, follow the [LiveKit agent quickstart](/docs/quickstart-livekit), then use the TTS configuration above.
* **Direct use:** call `stream()` when you use the plugin directly, because the WebSocket provider's `synthesize()` method raises an error. Call `end_input()` to finish input, then keep reading until synthesis ends. Both encodings produce decoded PCM frames.

## Plugin parameters

These settings apply to both encodings:

| Plugin option | Default | Behavior or wire field |
| - | - | - |
| `websocket_url` | Required to select v1 | Full endpoint, such as `wss://coda.api.rime.ai/ws`. A `/{model}/ws` path selects the model. |
| `model` | Read from a `/{model}/ws` path | Required when the path is only `/ws`, as on `coda.api.rime.ai`. Set `"coda"`. |
| `websocket_protocol` | `"binary"` | `"binary"` selects `rime.v1.binary`. `"json"` selects `rime.v1.json`. |
| `speaker` | `"lyra"` for Coda | `start.speaker`. Choose a [Coda voice](/docs/voices-coda). |
| `lang` | `"eng"` | `start.language`. The engine maps three-letter codes such as `eng` to two-letter tags such as `en`. |
| `audio_format` | `"audio/pcm"` | `start.audioParameters.audioFormat`. Accepts the six [canonical MIME types](/api-reference/coda/websocket-v1#audio-parameters). |
| `sample_rate` | `24000` for Coda | `start.audioParameters.samplingRate`. Set `8000` for 8 kHz telephony. |
| `time_scale_factor` | Omitted, engine default `1.0` | `start.audioParameters.timeScaleFactor`. Below `1` is faster. Above `1` is slower. |
| `api_key` | `RIME_API_KEY` environment variable | Bearer credential in the upgrade header. |
| `tokenizer` | Blingfire sentence tokenizer with `min_sentence_len=1` | Local text buffering. Custom tokenizers must emit complete sentences or stable clauses. |
| `http_session` | LiveKit-managed session | Outside an agent runtime, supply an `aiohttp.ClientSession` and close it yourself. |

For 8 kHz mu-law, set both `audio_format="audio/pcmu"` and `sample_rate=8000`. The format alone leaves Coda at 24 kHz. The plugin decodes mu-law to 16-bit PCM at the selected rate.

### Protocol limits

For `splitStrategy`, `config.defaults`, or `codaParameters.textLookaheadTokens`, use a [direct client](/api-reference/coda/websocket-v1-json). The adapter does not expose these fields or provide aligned word timestamps.

### Move from WS3 to v1

Use `websocket_url` and `model` for the endpoint, and `time_scale_factor` for speed. Remove these settings, because the v1 adapter rejects them:

| Purpose | Settings to remove |
| - | - |
| Legacy connection | `base_url`, `use_websocket=True` |
| Segmentation and latency | `segment`, `reduce_latency` |
| Speed | `speed_alpha` |
| Generation | Controls such as `temperature` |

## Stream lifecycle

One LiveKit stream uses one Coda context. The adapter opens the context when the first non-empty sentence is ready and uses a pooled connection that has already received `ready`.

| LiveKit action | Adapter behavior |
| - | - |
| `speech.prewarm()` | Open a pooled connection before the first turn. Call from a running async context. |
| `stream.push_text(text)` | Buffer fragments locally. Send complete sentences as `text`, after an empty `start`. |
| `stream.flush()` | Release the local tokenizer buffer as `text`. Keep the same context open for more input. |
| `stream.end_input()` | Drain final text and send `end`. Continue to receive audio until `done`. |
| `stream.aclose()` before completion | Send `cancel` and drain the terminal response. Discard the connection if cleanup fails. |
| `speech.aclose()` | Close tracked streams and pooled sockets. |

The adapter also works in these ways:

* **Flush:** call `flush()` only at a complete sentence or stable clause boundary. It can release incomplete buffered text, and there is no server-side `flush` operation. An input pause needs no message, and only `end_input()` finishes normal input.
* **Connections:** sequential turns reuse pooled connections. Concurrent LiveKit streams use separate sockets.
* **Options:** `speech.update_options(...)` changes settings for later streams. Active streams keep their initial settings.
* **Checks:** the plugin checks the subprotocol, `ready.protocol`, context IDs, and event order. It discards connections after malformed responses or failed cancellation cleanup.
* **Timeouts:** set connection and terminal timeouts with `speech.stream(conn_options=...)`, using LiveKit's `APIConnectOptions`.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.