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

# LiveKit

> LiveKit Virtual Avatar Plugin

The [LiveAvatar LiveKit plugin](https://docs.livekit.io/agents/models/avatar/plugins/liveavatar/) extends an existing [LiveKit Voice Agent](https://docs.livekit.io/agents/) into a functional video agent. You keep the same voice orchestration logic — you just get video on top of it.

<Note>
  This page assumes you already have a LiveKit project and a working LiveKit Agent. If not, start with LiveKit's [Voice AI quickstart](https://docs.livekit.io/agents/start/voice-ai/), or pick a different [integration path](/docs/lite-mode/integration-paths).
</Note>

<Tip>
  See the [LiveKit documentation](https://docs.livekit.io/agents/models/avatar/plugins/liveavatar/) for the upstream plugin reference.
</Tip>

## Prerequisites

* A LiveAvatar account and **API key**. Sign up at [app.liveavatar.com](https://app.liveavatar.com).
* A working **LiveKit Agents** setup (1.5.x recommended).

## Installation

```shell theme={null}
uv add "livekit-agents[liveavatar]~=1.5"
```

`pip install "livekit-agents[liveavatar]~=1.5"` works as well if you are not on `uv`.

## Configuration

The plugin reads two values from the environment:

```bash theme={null}
LIVEAVATAR_API_KEY=...   # required — your LiveAvatar key
LIVEAVATAR_AVATAR_ID=... # optional — overridden by avatar_id= kwarg if set
```

`LIVEAVATAR_AVATAR_ID` is a fallback. Passing `avatar_id="..."` to `AvatarSession` always wins.

## How LiveKit + LiveAvatar fit together

A LiveKit **room** hosts the conversation between three key participants:

| Participant    | Publishes                                           | Subscribes to                |
| -------------- | --------------------------------------------------- | ---------------------------- |
| **End user**   | Microphone audio                                    | Avatar audio + video         |
| **Your agent** | (no media; processes user audio, drives the avatar) | User microphone              |
| **Avatar**     | Lip-synced audio + video                            | Audio frames from your agent |

The LiveAvatar plugin handles two things on your agent's behalf:

1. **Adds the LiveAvatar into your room.** It spins up the avatar worker, which joins as a participant.
2. **Streams agent audio to LiveAvatar.** Instead of your agent publishing audio into the room, the plugin forwards it to LiveAvatar, which syncs it to the avatar's video output.

Everything else — STT, LLM, TTS, turn detection, room ownership — stays with your agent.

```mermaid theme={null}
graph TB
    subgraph Room["LiveKit room (you own)"]
        Agent["Your LiveKit agent<br/>(STT / LLM / TTS)"]
        User["End user"]
        Avatar["LiveAvatar<br/>avatar participant"]
    end
    User -->|"mic audio"| Agent
    Agent -->|"TTS audio frames"| Avatar
    Avatar -->|"lip-synced audio + video"| User
```

### How the plugin starts up

1. **Creates room.** Your backend creates the room through LiveKit and dispatches an agent worker into it.
2. **Starts avatar session.** The worker starts a LiveAvatar session, adding it into the room as a participant.
3. **Starts agent.** The agent session starts up as normal, running STT → LLM → TTS. Synthesized audio flows to the avatar instead of publishing as raw TTS.

The end user can join at any point after step 1 — before, during, or after the avatar appears.

## Usage

Drop `AvatarSession` into your existing agent entrypoint. The only new lines are the import, the `AvatarSession` construction, and the `await avatar.start(...)` call before `session.start(...)`.

```python theme={null}
from livekit import agents
from livekit.agents import AgentServer, AgentSession
from livekit.plugins import liveavatar

server = AgentServer()

@server.rtc_session(agent_name="my-agent")
async def my_agent(ctx: agents.JobContext):
    session = AgentSession(
        # ... your existing stt, llm, tts, vad, turn_detection
    )

    avatar = liveavatar.AvatarSession(
        avatar_id="...",  # or rely on LIVEAVATAR_AVATAR_ID
    )

    # Avatar joins the room and hooks the session's TTS output.
    await avatar.start(session, room=ctx.room)

    # Now start the conversation loop.
    await session.start(
        # ... room, agent, room_options, etc.
    )
```

### What changes versus a non-avatar agent

| Concern              | Non-avatar agent                 | With LiveAvatar plugin                                  |
| -------------------- | -------------------------------- | ------------------------------------------------------- |
| Where TTS audio goes | Published directly into the room | Forwarded to LiveAvatar; avatar publishes audio + video |
| Room participants    | User + agent                     | User + agent + avatar                                   |
| Frontend rendering   | Audio-only                       | Must subscribe to avatar's video track too              |
| Billing              | LiveKit + your inference         | LiveKit + your inference + LiveAvatar minutes           |

## Parameters

The most common `AvatarSession` parameters:

* **`avatar_id`** *(string)* — ID of the LiveAvatar avatar to use. Overrides `LIVEAVATAR_AVATAR_ID`.
* **`is_sandbox`** *(bool)* — Toggles [Sandbox Mode](/docs/sandbox-mode) for free testing without consuming credits.
* **`video_quality`** *(VideoQuality)* — Sets the avatar's video resolution.

See the [plugin reference](https://docs.livekit.io/reference/python/livekit/plugins/liveavatar/index.html) for the full parameter list.

## Resources

<CardGroup cols={2}>
  <Card title="livekit-plugins-liveavatar" icon="github" href="https://github.com/livekit/agents/tree/main/livekit-plugins/livekit-plugins-liveavatar">
    GitHub source for the LiveKit LiveAvatar plugin.
  </Card>

  <Card title="PyPI package" icon="python" href="https://pypi.org/project/livekit-plugins-liveavatar/">
    `livekit-plugins-liveavatar` on PyPI.
  </Card>
</CardGroup>
