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

# LiveKit Agents

> Use the Protoface avatar plugin in a LiveKit Agents app.

If your voice agent runs on LiveKit Agents, `livekit-plugins-protoface` is
the quickest way to add an avatar. It starts a Protoface session and joins
the avatar to your room as a participant, then streams your agent's audio
to it.

LiveKit maintains and publishes the plugin, and documents it at
[docs.livekit.io](https://docs.livekit.io/agents/models/avatar/plugins/protoface/).

If you are not on LiveKit, Protoface works with many more platforms and
SDKs. See [Other integrations](/guides/more-integrations).

## Install

```bash theme={null}
pip install livekit-plugins-protoface
```

## Basic usage

Create an `AvatarSession` and start it before `session.start(...)`:

```python theme={null}
from livekit.plugins import protoface

avatar = protoface.AvatarSession(avatar_id="av_stock_001")
await avatar.start(session, room=ctx.room)

await session.start(
    agent=agent,
    room=ctx.room,
)
```

Once started, the plugin routes your agent's audio through a LiveKit
DataStream addressed to the avatar participant.

## Token handling

`AvatarSession.start(...)` mints a short-lived room token in the agent
process from your LiveKit API key and secret, then passes it to Protoface
as `worker_token`. Your secret never leaves the agent process.

## Configuration

Set these in the agent environment.

| Variable | Required | Used for |
| - | - | - |
| `PROTOFACE_API_KEY` | yes | Authenticates calls to Protoface. |
| `PROTOFACE_API_URL` | no | Overrides `https://api.protoface.com`. |
| `LIVEKIT_URL` | yes | The LiveKit server the avatar joins. |
| `LIVEKIT_API_KEY` | yes | Used locally to mint the avatar room token. |
| `LIVEKIT_API_SECRET` | yes | Used locally to mint the avatar room token. Do not expose it to clients. |

Or pass them directly:

```python theme={null}
avatar = protoface.AvatarSession(
    avatar_id="av_stock_001",
    api_key="sk_live_...",
)

await avatar.start(
    session,
    room=ctx.room,
    livekit_url="wss://your-project.livekit.cloud",
    livekit_api_key="...",
    livekit_api_secret="...",
)
```

## AvatarSession options

| Option | Purpose |
| - | - |
| `avatar_id` | Avatar to render. Use an ID from the dashboard or `/v1/avatars`. |
| `api_key` | Protoface API key. Defaults to `PROTOFACE_API_KEY`. |
| `api_url` | Protoface API base URL. Defaults to `PROTOFACE_API_URL` or `https://api.protoface.com`. |
| `avatar_participant_identity` | LiveKit identity for the avatar participant. |
| `avatar_participant_name` | LiveKit display name for the avatar participant. |
| `max_duration_seconds` | Optional upper bound for the Protoface session. |
| `conn_options` | LiveKit Agents connection timeout and retry options. |

## Session

`avatar.start(...)` creates a Protoface session and puts its `sess_...` ID
on `avatar.session_id`. The session moves through `queued`, `starting`,
and `running`. `first_frame_at` is set when the first frame reaches the
room, and a `protoface-avatar-agent` participant publishes audio and
video into it.

```bash theme={null}
curl https://api.protoface.com/v1/sessions/sess_... \
  -H "Authorization: Bearer $PROTOFACE_API_KEY"
```

A session ends on `await avatar.aclose()` or `POST /v1/sessions/{id}/end`,
after `idle_timeout_seconds` without inbound audio, or at your plan's
duration cap. The idle default is 30 seconds, and the timer follows the
audio your agent sends rather than when the visitor stops speaking.

Billing rounds up to the minute, and `usage.billable_seconds` settles
after the fact rather than ticking live.
[Credits and limits](/reference/quotas) covers the caps.


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