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

# LiveKit Agents Integration

> Use LiveKit Agents and Spatius to build voice avatars.

export const LiveKitPluginDiagram = () => {
  return <div className="spatius-diagram not-prose" aria-label="LiveKit Agents Integration architecture">
      <svg viewBox="-83 0 1535 800" role="img">
        <defs>
          <marker id="spatius-livekit-rtc" viewBox="0 0 12 10" refX="10.5" refY="5" markerWidth="4.5" markerHeight="6" orient="auto-start-reverse">
            <path d="M0 0L12 5L0 10Z" fill="var(--spatius-diagram-livekit)" />
          </marker>
          <marker id="spatius-livekit-ink" viewBox="0 0 12 10" refX="10.5" refY="5" markerWidth="4.5" markerHeight="6" orient="auto-start-reverse">
            <path d="M0 0L12 5L0 10Z" fill="var(--spatius-diagram-ink)" />
          </marker>
        </defs>

        <text x="440" y="72" textAnchor="middle" fill="var(--spatius-diagram-red)" fontSize="30" fontWeight="600">You Managed</text>
        <text x="1000" y="72" textAnchor="middle" fill="var(--spatius-diagram-brand)" fontSize="30" fontWeight="600">Spatius Managed</text>

        <rect x="245" y="118" width="390" height="275" rx="18" fill="var(--spatius-diagram-owned)" stroke="var(--spatius-diagram-stroke)" strokeWidth="3" />
        <text x="440" y="148" textAnchor="middle" fill="var(--spatius-diagram-red)" fontSize="21" fontWeight="600">LiveKit Agents Worker</text>
        <rect x="285" y="168" width="310" height="112" rx="12" fill="var(--spatius-diagram-node)" stroke="var(--spatius-diagram-stroke)" strokeWidth="3" />
        <text x="440" y="204" textAnchor="middle" fill="var(--spatius-diagram-ink)" fontSize="29" fontWeight="500">
          <tspan x="440">AgentSession</tspan>
          <tspan x="440" dy="32" fill="var(--spatius-diagram-muted)" fontSize="21">STT / LLM / TTS</tspan>
          <tspan x="440" dy="27" fill="var(--spatius-diagram-muted)" fontSize="19">VAD / turns / tools</tspan>
        </text>
        <rect x="285" y="302" width="310" height="72" rx="12" fill="var(--spatius-diagram-node)" stroke="var(--spatius-diagram-stroke)" strokeWidth="3" />
        <text x="440" y="332" textAnchor="middle" fill="var(--spatius-diagram-ink)" fontSize="28" fontWeight="500">Spatius Plugin</text>
        <text x="440" y="360" textAnchor="middle" fill="var(--spatius-diagram-muted)" fontSize="19" fontWeight="500">livekit-plugins-spatius</text>
        <polyline points="608,338 865,338" className="spatius-diagram-flow" fill="none" stroke="var(--spatius-diagram-ink)" strokeWidth="4" strokeLinecap="round" markerEnd="url(#spatius-livekit-ink)" />

        <rect x="875" y="118" width="250" height="275" rx="18" fill="var(--spatius-diagram-managed)" stroke="var(--spatius-diagram-brand)" strokeWidth="3" />
        <text x="1000" y="245" textAnchor="middle" fill="var(--spatius-diagram-ink)" fontSize="31" fontWeight="500">
          <tspan x="1000">Motion</tspan>
          <tspan x="1000" dy="44">Server</tspan>
        </text>
        <polyline points="1000,400 1000,442" className="spatius-diagram-flow" fill="none" stroke="var(--spatius-diagram-livekit)" strokeWidth="4" strokeLinecap="round" markerEnd="url(#spatius-livekit-rtc)" />
        <polyline points="440,442 440,405" className="spatius-diagram-flow" fill="none" stroke="var(--spatius-diagram-livekit)" strokeWidth="4" strokeLinecap="round" markerEnd="url(#spatius-livekit-rtc)" />
        <rect x="310" y="452" width="750" height="82" rx="12" fill="var(--spatius-diagram-livekit-surface)" stroke="var(--spatius-diagram-livekit)" strokeWidth="3" />
        <text x="685" y="505" textAnchor="middle" fill="var(--spatius-diagram-ink)" fontSize="32" fontWeight="600">LiveKit room</text>

        <rect x="470" y="570" width="430" height="215" rx="18" fill="var(--spatius-diagram-owned)" stroke="var(--spatius-diagram-stroke)" strokeWidth="3" opacity="0.72" />
        <rect x="500" y="590" width="370" height="78" rx="12" fill="var(--spatius-diagram-managed)" stroke="var(--spatius-diagram-brand)" strokeWidth="3" />
        <text x="685" y="624" textAnchor="middle" fill="var(--spatius-diagram-ink)" fontSize="30" fontWeight="500">RTC Adapter</text>
        <text x="685" y="652" textAnchor="middle" fill="var(--spatius-diagram-muted)" fontSize="20" fontWeight="500">LiveKit provider</text>
        <polyline points="665,580 665,548" className="spatius-diagram-flow" fill="none" stroke="var(--spatius-diagram-livekit)" strokeWidth="4" strokeLinecap="round" markerEnd="url(#spatius-livekit-rtc)" />
        <polyline points="705,548 705,580" className="spatius-diagram-flow" fill="none" stroke="var(--spatius-diagram-livekit)" strokeWidth="4" strokeLinecap="round" markerEnd="url(#spatius-livekit-rtc)" />

        <rect x="535" y="705" width="300" height="70" rx="12" fill="var(--spatius-diagram-managed)" stroke="var(--spatius-diagram-brand)" strokeWidth="3" />
        <text x="685" y="734" textAnchor="middle" fill="var(--spatius-diagram-ink)" fontSize="27" fontWeight="500">AvatarKit SDK</text>
        <text x="685" y="760" textAnchor="middle" fill="var(--spatius-diagram-muted)" fontSize="19" fontWeight="500">client renderer</text>
        <polyline points="685,675 685,696" className="spatius-diagram-flow" fill="none" stroke="var(--spatius-diagram-ink)" strokeWidth="4" strokeLinecap="round" markerEnd="url(#spatius-livekit-ink)" />

        <g className="spatius-audio-visualizer" aria-label="user audio">
          <rect className="spatius-audio-bar" x="220" y="602" width="8" height="54" rx="4" />
          <rect className="spatius-audio-bar" x="238" y="588" width="8" height="82" rx="4" />
          <rect className="spatius-audio-bar" x="256" y="610" width="8" height="38" rx="4" />
          <rect className="spatius-audio-bar" x="274" y="582" width="8" height="94" rx="4" />
          <rect className="spatius-audio-bar" x="292" y="598" width="8" height="62" rx="4" />
        </g>
        <text x="260" y="696" textAnchor="middle" fill="var(--spatius-diagram-muted)" fontSize="28" fontWeight="500">user audio</text>
        <polyline points="335,630 490,630" className="spatius-diagram-flow" fill="none" stroke="var(--spatius-diagram-ink)" strokeWidth="4" strokeLinecap="round" markerEnd="url(#spatius-livekit-ink)" />
        <polyline points="847,740 1080,740" className="spatius-diagram-flow" fill="none" stroke="var(--spatius-diagram-ink)" strokeWidth="4" strokeLinecap="round" markerEnd="url(#spatius-livekit-ink)" />
        <text x="1102" y="750" textAnchor="start" fill="var(--spatius-diagram-ink)" fontSize="32" fontWeight="500">Avatar</text>
      </svg>
    </div>;
};

LiveKit Agents Integration is a **Platform Integration**. Use it when your voice agent runs in [LiveKit Agents](https://docs.livekit.io/agents/) and you want `livekit-plugins-spatius` to connect that agent worker to Motion Server. The package attaches to your agent and pipes agent audio to Motion Server; Motion Server publishes lip-synced audio and motion data back into the same LiveKit room.

LiveKit Agents is the platform integration; the [RTC Adapter](/sdk-reference/web-sdk/rtc-adapter) (`@spatius/avatarkit-rtc`) is the Web client adapter that renders the avatar stream from the LiveKit room. The LiveKit room itself is the transport.

<Note>
  **Web Only:** The current AvatarKit RTC client demo path targets Web. LiveKit ships iOS and Android client SDKs, but Spatius does not yet provide iOS or Android demos for this path.
</Note>

## At a glance

| Dimension            | LiveKit Agents Integration                                                                                        |
| -------------------- | ----------------------------------------------------------------------------------------------------------------- |
| **Dev effort**       | 🟢 Low if you already use LiveKit Agents; 🟡 Medium if you are adopting LiveKit too.                              |
| **Latency profile**  | ⚡ Ultra-low; agent audio is handled in the LiveKit worker and avatar output returns through the room.             |
| **You build**        | 🎙️ LiveKit Agents worker wiring, 🔌 Spatius plugin configuration, 🎟️ LiveKit token flow, and 🌐 Web RTC client. |
| **You do not build** | 🚫 A custom Server SDK pipeline or downstream transport.                                                          |
| **Best first demo**  | 🚀 [LiveKit Agents Integration quickstart](/quickstarts/livekit-agents).                                          |
| **Client support**   | 🌐 Web today                                                                                                      |

## Architecture

<Frame>
  <LiveKitPluginDiagram />
</Frame>

* **LiveKit room** handles transport.
* **Agent worker** runs your voice agent with `livekit-plugins-spatius` attached.
* **Motion Server** generates motion data from the agent audio and publishes the synchronized audio + motion stream back into the room.
* **AvatarKit RTC client** joins the room and renders the avatar.

Spatius is not a video streaming service. Even when you use LiveKit as the transport layer and LiveKit Agents as the voice agent framework, LiveKit transports avatar audio and motion data, not finished avatar video. `@spatius/avatarkit` renders the avatar locally in the browser.

## Frontend installation

<Tabs>
  <Tab title="pnpm">
    ```bash theme={null}
    pnpm add @spatius/avatarkit-rtc @spatius/avatarkit
    ```
  </Tab>

  <Tab title="npm">
    ```bash theme={null}
    npm install @spatius/avatarkit-rtc @spatius/avatarkit
    ```
  </Tab>

  <Tab title="yarn">
    ```bash theme={null}
    yarn add @spatius/avatarkit-rtc @spatius/avatarkit
    ```
  </Tab>

  <Tab title="bun">
    ```bash theme={null}
    bun add @spatius/avatarkit-rtc @spatius/avatarkit
    ```
  </Tab>
</Tabs>

## Frontend setup

<Steps>
  <Step title="Toolchain setup">
    Configure your build tool to load the AvatarKit WebAssembly assets. See [Toolchain Setup](/sdk-reference/web-sdk/toolchain).
  </Step>

  <Step title="Pick a UI path">
    * For drop-in React components, use [AvatarKit UI](/sdk-reference/web-sdk/avatarkit-ui).
    * To own the UI and connection flow yourself, use the JavaScript API below.
  </Step>

  <Step title="JavaScript API (custom UI)">
    <Accordion title="Step-by-step JS API setup">
      <Steps>
        <Step title="Initialize SDK">
          ```typescript theme={null}
          import { AvatarSDK, DrivingServiceMode } from '@spatius/avatarkit'

          await AvatarSDK.initialize('your-app-id', {
            drivingServiceMode: DrivingServiceMode.backend,
          })
          ```
        </Step>

        <Step title="Load Avatar & Create View">
          ```typescript theme={null}
          const avatar = await AvatarManager.shared.load('avatar-id')
          const container = document.getElementById('avatar-container')!
          const avatarView = new AvatarView(avatar, container)
          ```
        </Step>

        <Step title="Create Player with LiveKit Provider">
          ```typescript theme={null}
          import { AvatarPlayer, LiveKitProvider } from '@spatius/avatarkit-rtc'

          const provider = new LiveKitProvider()
          const player = new AvatarPlayer(provider, avatarView, {
            logLevel: 'warning',
          })
          ```
        </Step>

        <Step title="Connect to LiveKit Server">
          ```typescript theme={null}
          await player.connect({
            url: 'wss://your-livekit-server.com',
            token: 'your-livekit-token',
            roomName: 'room-name',
          })
          ```
        </Step>

        <Step title="Start voice interaction">
          ```typescript theme={null}
          // Start microphone publishing
          await player.startPublishing()

          // Stop microphone
          await player.stopPublishing()

          // Disconnect when done
          await player.disconnect()
          ```
        </Step>
      </Steps>
    </Accordion>

    Full RTC client API reference: [LiveKit Agents Client](/livekit-agents/client).
  </Step>
</Steps>

## LiveKit Agents plugin installation

<Tabs>
  <Tab title="pip">
    ```bash theme={null}
    pip install livekit-plugins-spatius
    ```
  </Tab>

  <Tab title="uv">
    ```bash theme={null}
    uv add livekit-plugins-spatius
    ```
  </Tab>
</Tabs>

## Server setup

If you already use [LiveKit Agents](https://docs.livekit.io/agents/), add `livekit-plugins-spatius` to your agent worker. The package attaches to your `AgentSession` and pipes TTS audio to Spatius; Motion Server publishes the resulting audio and motion data to the same LiveKit room.

Required environment variables:

* Spatius: `SPATIUS_API_KEY`, `SPATIUS_APP_ID`, `SPATIUS_AVATAR_ID`
* Optional region: `SPATIUS_REGION` defaults to `us-west`
* LiveKit: `LIVEKIT_URL`, `LIVEKIT_API_KEY`, `LIVEKIT_API_SECRET`

Create an `AvatarSession` and start it with your agent session and room:

```python theme={null}
from livekit.agents import AgentSession, JobContext
from livekit.plugins import spatius

async def entrypoint(ctx: JobContext):
    await ctx.connect()

    session = AgentSession(vad=vad, stt=stt, llm=llm, tts=tts)
    avatar = spatius.AvatarSession()
    await avatar.start(session, room=ctx.room)

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

See the [LiveKit Agents Integration Server guide](/livekit-agents/server) for the full `livekit-plugins-spatius` flow, interruption behavior, and API links.

## Next steps

<CardGroup cols={3}>
  <Card title="Quickstart" icon="bolt" href="/quickstarts/livekit-agents">
    Run the end-to-end LiveKit Agents voice avatar demo.
  </Card>

  <Card title="Server" icon="server" href="/livekit-agents/server">
    Add `livekit-plugins-spatius` to your LiveKit Agents worker.
  </Card>

  <Card title="Client" icon="globe" href="/livekit-agents/client">
    Render the avatar in your Web app with `@spatius/avatarkit-rtc`.
  </Card>
</CardGroup>
