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

# LiveKit Integration

> Use Lokutor speech to text and text to speech in LiveKit Agents with the livekit-plugins-lokutor plugin.

[LiveKit Agents](https://docs.livekit.io/agents/) is an open-source Python framework for realtime voice agents. The Lokutor plugin, `livekit-plugins-lokutor`, is part of the [livekit/agents](https://github.com/livekit/agents/tree/main/livekit-plugins/livekit-plugins-lokutor) repository (merged on 2026-11-12 in [livekit/agents#7256](https://github.com/livekit/agents/pull/7256)). It adds two services to an `AgentSession`:

* `lokutor.STT`: Conv 2.0 speech to text, streaming over [`/ws/stt`](https://docs.lokutor.com/sdk/stt#raw-ws-stt-protocol).
* `lokutor.TTS`: Versa 2.0 text to speech, streaming over [`/ws/tts`](https://docs.lokutor.com/api-reference/streaming).

Both cover English, Spanish, Catalan, Galician, Basque, Portuguese, French, Italian and German. LiveKit runs the LLM, turn-taking and the room; Lokutor hears the user and speaks the replies.

## Installation

```bash theme={null}
pip install "livekit-agents[lokutor]~=1.8"
```

> [!NOTE]
>
> The plugin is published to PyPI with the first LiveKit Agents release after 1.8.11. Until that release, install it from GitHub:
>
> ```bash theme={null}
> GIT_LFS_SKIP_SMUDGE=1 pip install "livekit-plugins-lokutor @ git+https://github.com/livekit/agents@main#subdirectory=livekit-plugins/livekit-plugins-lokutor"
> ```
>
> `GIT_LFS_SKIP_SMUDGE=1` skips the example media files that the LiveKit repository keeps in Git LFS; without it the clone can fail.

## Authentication

Create an API key in the [dashboard](https://app.lokutor.com) and set it as `LOKUTOR_API_KEY`, or pass `api_key=` to `lokutor.STT` and `lokutor.TTS`.

## A voice agent

```python theme={null}
from dotenv import load_dotenv

from livekit.agents import Agent, AgentServer, AgentSession, JobContext, cli
from livekit.plugins import lokutor, openai, silero

load_dotenv()

server = AgentServer()


@server.rtc_session()
async def entrypoint(ctx: JobContext) -> None:
    session = AgentSession(
        stt=lokutor.STT(language="es"),
        llm=openai.LLM(),
        tts=lokutor.TTS(voice="F1", language="es"),
        vad=silero.VAD.load(),
    )
    await session.start(
        agent=Agent(instructions="Eres una recepcionista amable. Responde en frases cortas, sin listas ni emojis."),
        room=ctx.room,
    )
    await session.generate_reply(instructions="Saluda y pregunta en qué puedes ayudar.")


if __name__ == "__main__":
    cli.run_app(server)
```

This example also needs `pip install "livekit-agents[openai,silero]~=1.8" python-dotenv` and an `OPENAI_API_KEY`; any LiveKit LLM plugin works in its place. Run `python agent.py console` to talk to the agent in your terminal, or `python agent.py dev` to connect it to a LiveKit server (`LIVEKIT_URL`, `LIVEKIT_API_KEY`, `LIVEKIT_API_SECRET`).

Keep `language` the same on both services: it chooses how the recogniser writes the text and which native speaker the voice slot uses.

## Speech to text

```python theme={null}
stt = lokutor.STT(language="en")
```

| Parameter | Type | Default | Description |
| :- | :- | :- | :- |
| `api_key` | `str` | env `LOKUTOR_API_KEY` | Lokutor API key |
| `language` | `str` | detected | One of the nine languages; regional codes such as `es-ES` are accepted. Set it whenever you know it: it keeps one-word replies reliable and sets how the text is written. Unset, or any other language, the language is detected |
| `base_url` | `str` | `"wss://api.lokutor.com"` | API base URL |
| `http_session` | `aiohttp.ClientSession` | the job's | Pass your own outside an agent job (see [Outside an agent](#outside-an-agent)) |

* **Streaming:** interim transcripts while the user speaks, then a final transcript when the utterance ends, after about 0.7 s without speech ([how utterances end](https://docs.lokutor.com/sdk/stt.md)). The text comes back written out, with punctuation, casing and digits.
* **Audio:** frames at any sample rate; the plugin resamples to the 16 kHz the API takes.
* **One clip:** `await stt.recognize(frames)` transcribes a list of `rtc.AudioFrame` with one `POST /stt/transcribe` request.
* **Not exposed:** [custom vocabulary](https://docs.lokutor.com/guides/custom-vocabulary.md) (`keyterms`) and word timings.

## Text to speech

```python theme={null}
tts = lokutor.TTS(voice="F1", language="en")
```

| Parameter | Type | Default | Description |
| :- | :- | :- | :- |
| `api_key` | `str` | env `LOKUTOR_API_KEY` | Lokutor API key |
| `voice` | `str` | `"F1"` | Voice slot, `F1`-`F5` or `M1`-`M5`, or one of your `clone_…` ids. Each language has its own native speaker in each slot ([Voices](https://docs.lokutor.com/voices-languages-models.md#voices)) |
| `language` | `str` | `"en"` | One of the nine languages with their own speakers; the other languages the API speaks use the English speakers ([Languages](https://docs.lokutor.com/voices-languages-models.md#languages)) |
| `tokenizer` | `tokenize.SentenceTokenizer` | `blingfire` | Splits the LLM's streamed text into sentences; each sentence is one request, so each has its own prosody |
| `base_url` | `str` | `"wss://api.lokutor.com"` | API base URL |
| `http_session` | `aiohttp.ClientSession` | the job's | Pass your own outside an agent job |

* **Audio:** 16-bit PCM, 44.1 kHz, mono. LiveKit resamples it if the room needs another rate.
* **Sentences:** the first sentence is sent as soon as the tokenizer completes it, so the agent starts speaking before the LLM has finished the reply.
* **Pronunciation:** your account's default [pronunciation dictionary](https://docs.lokutor.com/api-reference/pronunciation.md) applies to every sentence.
* **Server defaults:** `temperature` (0.3) and the other `/ws/tts` fields the plugin does not send keep their [defaults](https://docs.lokutor.com/api-reference/streaming.md#request).

## Outside an agent

Inside an agent job, LiveKit supplies the HTTP session. In a script or a test, pass your own:

```python theme={null}
import asyncio

import aiohttp
from livekit.plugins import lokutor


async def main() -> None:
    async with aiohttp.ClientSession() as http:
        tts = lokutor.TTS(voice="F1", language="es", http_session=http)
        stt = lokutor.STT(language="es", http_session=http)

        stream = tts.stream()
        stream.push_text("Hola, soy tu asistente. ")
        stream.push_text("¿En qué puedo ayudarte hoy?")
        stream.end_input()
        frames = [ev.frame async for ev in stream]

        event = await stt.recognize(frames)
        print(event.alternatives[0].text)  # Hola, soy tu asistente. ¿En qué puedo ayudarte hoy?

        await tts.aclose()
        await stt.aclose()


asyncio.run(main())
```

## Concurrency and billing

* **Two sessions per agent.** While an `AgentSession` runs it holds one `/ws/stt` stream and one `/ws/tts` socket, and each counts as one of your account's concurrent sessions ([Limits](https://docs.lokutor.com/pricing.md#limits)): 3 before the first top-up, 10 after. An account carries **one** LiveKit agent at a time before its first top-up and **five** after; past that, the next connection is refused (`429` / `auth.rate_limited`). Higher limits on request.
* **Billing.** The same prices as calling the API directly, from your prepaid balance: speech to text per minute of audio, text to speech per million characters ([rate card](https://docs.lokutor.com/api-reference/rate-card.md)). The LLM and LiveKit itself are billed by their providers.

## When to use Lokutor's own agent instead

The plugin brings Lokutor's voices and recognition into a LiveKit pipeline. To run the whole conversation on Lokutor (LLM, turn-taking, tools, phone numbers, call recording), use a [Lokutor agent](https://docs.lokutor.com/guides/my-first-agent.md) and the [Voice Agent API](https://docs.lokutor.com/api-reference/voice-chat.md) instead.

## Resources

* **Source:** [https://github.com/livekit/agents/tree/main/livekit-plugins/livekit-plugins-lokutor](https://github.com/livekit/agents/tree/main/livekit-plugins/livekit-plugins-lokutor)
* **Pull request:** [https://github.com/livekit/agents/pull/7256](https://github.com/livekit/agents/pull/7256)
* **PyPI:** [https://pypi.org/project/livekit-plugins-lokutor/](https://pypi.org/project/livekit-plugins-lokutor/) (from the next LiveKit Agents release)
* **LiveKit Agents docs:** [https://docs.livekit.io/agents/](https://docs.livekit.io/agents/)


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