Skip to main content
Live monitoring Voice simulations Chat simulations

Overview

The self-hosted LiveKit integration monitors voice agents built on the open-source LiveKit Agents framework that run against your own LiveKit server. Drop the roark-analytics[livekit] helper into your agent entrypoint and call lifecycle, transcripts, tool calls, and a recording are forwarded to Roark automatically — no other code changes required. The SDK talks only to Roark’s own API; it never connects to your LiveKit server.
Using LiveKit Cloud? You can use this SDK there too, but the dashboard-managed webhook integration is usually simpler — see LiveKit Cloud.

Prerequisites

  • A LiveKit Agents worker (Python 3.10+, livekit-agents 1.x)
  • Your own LiveKit server
  • A Roark API key with WRITE scope (generate one)

Setup Instructions

Step 1: Install the SDK

Step 2: Configure your API key

The only setting you need to provide is your Roark API key.
.env

Step 3: Wire observe_session into your entrypoint

Call observe_session(...) before session.start() so the audio taps are installed before the session begins streaming frames. That single call wires up everything:
That’s the full integration — agent registration, transcripts, tool calls, and the recording are all handled by the helper.

Step 4: Verify the connection

Run your worker against your LiveKit server and place a test call:
As the call runs you should see Roark log lines, then the recording upload begin after a few seconds of audio:
Within a few seconds you should also see, in your Roark dashboard:
  1. The agent appear under the LiveKit source filter
  2. The call appear in the calls table with status In Progress
  3. After the call ends — the transcript, tool invocations, and recording attached to the call

How It Works

observe_session subscribes to the standard AgentSession event surface and ships a compact event timeline to Roark: Failures are logged and swallowed — the helper never raises into your session. Your agent keeps running even if Roark is unreachable.

What Gets Synced

  • Calls — Lifecycle with timing and end reason
  • Agents — Lazy-registered on first sight using the agent_id / agent_name you pass
  • Prompts — System prompt captured at call start as a prompt revision
  • Transcripts — Per-turn messages with role, content, and timestamp
  • Tool Invocations — Tool call IDs, names, JSON arguments, and results
  • Recordings — Audio recording of the call
Roark only sees what the helper forwards. If you remove observe_session from a worker — or set ROARK_OBSERVABILITY_ENABLED=false — no data flows for those calls.

Agent Management

LiveKit agents are lazy-registered the first time the helper reports them:
  • The first call-started event with a new agent_id creates the agent in Roark
  • Subsequent events update the agent’s name and prompt if they change
  • These agents appear on the agents page under the LiveKit source filter
Once an agent exists, it can be used in simulations, run plans, and agent reports just like agents from any other provider.

Kill Switch

Disable instrumentation at runtime without touching code. Set ROARK_OBSERVABILITY_ENABLED=false to make observe_session a no-op (it returns None). Values treated as off: false, 0, no, off (case-insensitive); anything else (or the variable being absent) keeps it enabled.

Troubleshooting

The helper registers a shutdown callback on the JobContext, which fires when LiveKit ends the job. If your transport tears down without firing the hook, call await state.aflush(reason="...") explicitly from your own disconnect handler — aflush() is idempotent, so the normal shutdown path will no-op if both fire.
Transcripts come from the conversation_item_added event on AgentSession. If you use a custom pipeline that bypasses AgentSession.start(room=…, agent=…), that event may never fire — verify by adding your own session.on("conversation_item_added", print) listener.
The user side is tapped from session.input.audio; the agent side from session.output.audio. Because the taps are installed by observe_session, it must be called before session.start(). Check worker logs for the tapping user audio input / tapping agent audio output lines — if one is missing, that side will be silent on the merged recording.
Confirm api_key is a WRITE-scope key and that ROARK_OBSERVABILITY_ENABLED is not set to a falsy value.

Next Steps

Enable Tracing

Send OpenTelemetry traces — they auto-link to the call via the room sid

Run Simulations

Test your LiveKit agents

Configure Evaluators

Set up evaluation criteria

LiveKit Cloud

Use the dashboard-managed webhook integration instead