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

# LiveKit Cloud

> Connect LiveKit Cloud for real-time voice communication monitoring

<Badge color="green">Live monitoring</Badge> <Badge color="green">Voice simulations</Badge> <Badge color="gray" stroke>Chat simulations</Badge>

## Overview

The LiveKit Cloud integration enables real-time monitoring of voice communications built on [LiveKit Cloud](https://cloud.livekit.io/). Roark connects to your LiveKit project over webhooks and the server API — no changes to your agent code — and streams call data in for analysis, evaluation, and quality monitoring.

<Note>
  Running your own `livekit-server` instead of LiveKit Cloud? Webhooks and the dashboard-managed flow described here still work, but the recommended path for self-hosted deployments is the drop-in Python SDK. See [LiveKit (self-hosted)](/documentation/integrations/livekit-self-hosted).
</Note>

***

## Prerequisites

Before setting up the integration, ensure you have:

* A [LiveKit Cloud](https://cloud.livekit.io/) account and project
* LiveKit API credentials (API Key and Secret)
* Admin access to configure webhooks in LiveKit

***

## Setup Instructions

### Step 1: Create Integration

1. Navigate to **Agents** in your Roark dashboard
2. Click **Connect Agent** in the top right, choose **Existing Platform**, and select **LiveKit**
3. Enter the following configuration:

| Field                | Description                        | Example                       |
| :------------------- | :--------------------------------- | :---------------------------- |
| **Integration Name** | Friendly name for this integration | Production LiveKit            |
| **Server URL**       | Your LiveKit WebSocket URL         | `wss://example.livekit.cloud` |
| **API Key**          | LiveKit API key                    | `APIxxxxxxxxxxxxx`            |
| **API Secret**       | LiveKit API secret                 | Keep this secure              |

### Step 2: Configure Webhook

After creating the integration, Roark provides a webhook URL:

1. Copy the webhook URL from the integration settings
2. Navigate to your LiveKit dashboard
3. Go to **Settings → Webhooks**
4. Add the Roark webhook URL
5. Select the following events:
   * `room_started`
   * `room_finished`
   * `participant_joined`
   * `egress_ended`

### Step 3: Configure Agents

Under the **Agents** section of the integration, decide how LiveKit calls map to Roark agents:

* **Import named LiveKit agents** — Roark fetches the named agents configured in your LiveKit project so you can choose which ones to track. Each imported agent becomes its own Roark agent, and calls are routed based on the LiveKit agent name that participated in the room.
* **Assign all calls to a single Roark agent** — Pick one Roark agent and every call from this integration is attributed to it. Use this when you rely on LiveKit's automatic dispatch (unnamed agents) or when you don't care about distinguishing multiple agents.

<Note>
  You can switch between these modes later, but existing calls will keep the agent attribution they had at ingest time.
</Note>

### Step 4: WebRTC Endpoints (optional)

The **WebRTC** section of the integration page is where you manage all LiveKit WebRTC endpoints for this integration. On first setup it can auto-create one endpoint per imported agent so you can start running simulations immediately; after the integration exists you can come back to this same section at any time to add, edit, or remove endpoints. See [WebRTC Endpoints](#webrtc-endpoints) below for the full list of settings — you can skip this step and add endpoints later if you prefer.

### Step 5: Configure Metric Collectors

Calls synced from LiveKit are scored by your [metric collectors](/documentation/metrics/metric-collectors). Set them up globally under **Metrics → Collectors**, or scope collectors to a specific agent from that agent's **Collectors** section.

### Step 6: Activate Integration

Toggle the integration status to **Active** to begin receiving call data.

***

## WebRTC Endpoints

Roark can run simulations directly over WebRTC against a LiveKit room instead of placing a phone call. This is the recommended path for LiveKit agents because it avoids SIP trunking and exercises the exact transport your production users connect over.

### Managing WebRTC Endpoints

All LiveKit WebRTC endpoints for an integration are managed from the **WebRTC** section of the integration page:

1. Go to **Agents**, expand the connected sources at the top of the page, and choose your **LiveKit** source. The integration form opens on the right.
2. Expand the **WebRTC** section to see every endpoint attached to an agent that belongs to this integration. Each row shows the agent name and environment.
3. Click an existing endpoint to edit it, or click **Add WebRTC endpoint** to create a new one. The add flow opens the same editor used on the agent page and is scoped to agents managed by this integration.

<Note>
  On initial integration setup, Roark can also auto-create one WebRTC endpoint per imported agent in a single step — see [Step 4: WebRTC Endpoints](#step-4-webrtc-endpoints-optional) above. After the integration exists, use the flow described here for every change.
</Note>

### Room Management Mode

When configuring the endpoint you pick who is responsible for creating the LiveKit room that a simulation runs in.

<Tabs>
  <Tab title="Roark manages the room">
    Roark creates the room in your LiveKit project at the start of each simulation using the API credentials from the integration, then joins the room as the simulated caller.

    * **Agent dispatch** — If a **Named LiveKit Agent** is set on the integration, Roark explicitly dispatches that agent into the room so it joins as soon as the room is created. If no named agent is set, Roark relies on LiveKit's [automatic dispatch](https://docs.livekit.io/agents/worker/agent-dispatch/) behavior — any unnamed worker connected to your LiveKit project will pick up the room automatically.
    * **Room metadata** — Optionally provide a JSON string that Roark attaches to the room it creates. Use this to pass context to your agent (for example, a customer ID, scenario tag, or feature flag) that your worker can read from the room metadata on join.

    This mode is the easiest to set up and works for most agents that use LiveKit's standard dispatch model.
  </Tab>

  <Tab title="You manage the room">
    Provide an HTTPS URL that Roark calls when a simulation starts. Your endpoint is responsible for creating the LiveKit room, dispatching your agent into it, and returning the room name so Roark can join.

    **Request** — Roark sends an HTTPS request to your URL when a simulation starts.

    **Expected response** — Return a JSON body containing the `roomName` of the LiveKit room you created. Roark then connects to the same LiveKit server and joins that room as the simulated caller.

    ```json theme={"theme":{"light":"everforest-light","dark":"everforest-dark"}}
    {
      "roomName": "sim-session-abc123"
    }
    ```

    Use this mode when you need custom room setup logic — for example, if you provision rooms through your own backend, need to wire up per-session tokens or tools, or run a bespoke dispatch flow that Roark's auto-create path can't express.
  </Tab>
</Tabs>

Once the endpoint exists, use it like any other agent endpoint when building [run plans](/documentation/simulation-testing/run-plans) and [running simulations](/documentation/simulation-testing/running-simulations).

***

## What Gets Synced

LiveKit integrations sync the following data:

* **Call Events** - Room creation, participant joining, call completion
* **Recording Files** - MP4 recordings from egress events
* **Call Metadata** - Duration, participant count, room configuration
* **Transcripts** - When speech-to-text is enabled
* **Named Agents** - When agent import is enabled in the [Agents](#step-3-configure-agents) step, the list of named LiveKit agents from your project

<Warning>
  LiveKit does not sync agent prompts or worker source code, as it's a real-time
  communication platform rather than an AI agent provider. Only agent names are
  imported so Roark can attribute calls to the correct agent.
</Warning>

***

## Webhook Events

The integration processes these LiveKit events:

| Event                | Description     | Roark Action                      |
| :------------------- | :-------------- | :-------------------------------- |
| `room_started`       | Room created    | Initialize call record            |
| `room_finished`      | Room ended      | Finalize call, trigger evaluation |
| `participant_joined` | User joined     | Update participant list           |
| `egress_ended`       | Recording ready | Process recording file            |

***

## Call Sampling & Metadata Filtering

Roark provides two ways to control which LiveKit calls are processed:

### Random Sampling

Set a **sampling rate** (0–100%) in the integration settings to randomly sample a percentage of calls. This is useful when you want to evaluate a representative subset without any code changes.

### Metadata Filtering (Per-Call Control)

For more granular control, set `roark.skip` to `true` in your LiveKit room metadata to tell Roark to skip processing for specific calls.

<CodeGroup>
  ```python Python theme={"theme":{"light":"everforest-light","dark":"everforest-dark"}}
  from livekit import api

  room = api.CreateRoomRequest(
      name="my-room",
      metadata='{"roark.skip": true}'
  )
  ```

  ```typescript TypeScript theme={"theme":{"light":"everforest-light","dark":"everforest-dark"}}
  import { RoomServiceClient } from 'livekit-server-sdk';

  const roomService = new RoomServiceClient(url, apiKey, apiSecret);
  await roomService.createRoom({
    name: 'my-room',
    metadata: JSON.stringify({ 'roark.skip': true }),
  });
  ```
</CodeGroup>

**How it works:**

* Calls **without** `roark.skip` in metadata are processed normally (safe default)
* Calls **with** `roark.skip` set to `true` are skipped entirely — no recording, no evaluation, no processing
* The check happens at the webhook level, so skipped calls use zero Roark resources
* You can combine metadata filtering with sampling — sampling is applied first, then metadata filtering

<Note>
  Metadata filtering is ideal when you want deterministic control over which calls are processed, such as skipping internal test calls or only evaluating calls for specific customers.
</Note>

***

## Monitoring Integration Health

Check your integration status in the Roark dashboard:

* **Active** 🟢 - Receiving and processing events
* **Inactive** 🔴 - Integration paused
* **Error** ⚠️ - Configuration or connection issues

View recent webhook deliveries and any error messages in the integration details.

***

## Next Steps

<CardGroup cols={2}>
  <Card title="Enable Tracing" icon="git-branch" href="/documentation/observability/traces?tab=livekit">
    Send OpenTelemetry traces from your LiveKit agent
  </Card>

  <Card title="Configure Metrics" icon="gauge" href="/documentation/metrics/overview">
    Define metrics and pass/fail thresholds
  </Card>

  <Card title="View Live Calls" icon="phone" href="/documentation/observability/live-monitoring">
    Monitor calls in real-time
  </Card>

  <Card title="Integration Overview" icon="plug" href="/documentation/integrations/overview">
    Learn about all integrations
  </Card>

  <Card title="Self-hosted LiveKit" icon="server" href="/documentation/integrations/livekit-self-hosted">
    Instrument your own livekit-server with the Python SDK
  </Card>
</CardGroup>
