Skip to main content
This guide covers both the Python SDK (tuner-livekit-sdk) and the Node.js SDK (@usetuner.ai/livekit-sdk). Use the language switcher below to view the guide for your stack.

Video Tutorial

Prerequisites

  • Tuner Active Account
  • Configured Agent with provider “Custom API” in Tuner
  • A LiveKit Agents project, either:

Overview

The Tuner LiveKit SDK automatically captures session data from your LiveKit agent and sends it to Tuner when the call ends — no manual API calls required. It ships in two flavours that share the same wire format and feature set: a Python package and a Node.js package.
1

Install the SDK

Add the package to your project.
2

Set Your Credentials

Configure your Tuner API key, workspace ID, and agent remote ID.
3

Add the Plugin

Drop two lines into your entrypoint and you’re done.
Estimated time: 2 minutes from start to finish

Step 1: Install the SDK

Requirements: Python ≥ 3.10, livekit-agents >= 1.4, aiohttp >= 3.9

Step 2: Set Your Credentials

You can configure credentials via environment variables or pass them directly in code.
Use the Agent Remote ID from Agent Settings → Agent Connection — not your agent’s display name. It is a UUID (for example fa4da74c-...). Copy your value from the Tuner dashboard.

Step 3: Add the Plugin

Import TunerPlugin and add it right after creating your AgentSession — before calling session.start():
That’s it. The plugin listens to session events and submits call data to Tuner when the session ends.

SIP correlation for simulation

To run Call Simulation against this agent, pass the inbound call’s SIP Call-ID as sip_correlation_id. For why Tuner needs it and how the value can change name in transit, see Simulation SIP setup.
This applies to inbound simulation, where Tuner dials your agent. For outbound simulation, pass the dialed SIP URI as recipient instead — see Outbound Simulation.
LiveKit exposes the value on the SIP participant as the sip.callIDFull attribute.
Requires tuner-livekit-sdk >= 0.1.5.

Helper: extract the SIP correlation ID

Add this helper to your entrypoint module. It scans the room’s remote participants for the SIP participant and returns its sip.callIDFull attribute.
For web calls (no SIP participant), this returns None and TunerPlugin falls back to its normal behaviour.

Wire it into your entrypoint

The SIP participant only becomes visible after the agent joins the room. Call ctx.connect() first, then read the correlation ID, then pass it to TunerPlugin:
If ctx.connect() runs after you try to read participants, ctx.room.remote_participants will be empty and sip_correlation_id will be None. Simulated calls will still complete, but they won’t be linked to their Tuner simulation rows.

Disconnection Reasons

Tuner captures why each call ended. User disconnects and errors are tracked automatically. To record agent-initiated hangups, pass reason="agent_hangup" when ending the call programmatically:
Without this, agent hangups are indistinguishable from dropped calls in your analytics.
drain=True lets any in-flight audio finish before the session closes. Omit it for an immediate cutoff.

LangChain / LangGraph observability

Using LangGraph or LangChain for your logic layer? The plugin can capture node transitions, tool calls, and timing alongside session data. See LangChain / LangGraph.

Configuration Options

The plugin auto-detects the call type (phone_call for SIP participants, web_call otherwise). Override it explicitly when needed:
The phone number or SIP URI of the callee. Optional — pass it when you want to record who the call was directed to:
Tuner requires a recording_url for every call. Provide a resolver function that returns the URL. If you don’t provide one, the plugin submits "pending" as a placeholder.
Provide a callable that receives a UsageSummary and returns the call cost in USD cents. Implement the method that matches your pricing plan; the snippet below is illustrative.
Attach arbitrary key-value data to every call record:
Track which version of your agent handled each call — useful when you update a prompt, swap a model, or change your pipeline:
Tuner reads it automatically. Bump the number on every deployment.Override in code (takes priority over the env var):
Useful for local development or test environments:

Full Example

Troubleshooting

  • Verify that TUNER_AGENT_ID is the Agent Remote ID from Agent Settings → Agent Connection (not your agent’s display name).
  • Confirm TUNER_WORKSPACE_ID is correct.
  • Check your application logs for any error messages from the plugin.
  • Ensure TUNER_API_KEY starts with tr_api_ and is valid.
  • Confirm the API key belongs to the correct workspace.
  • You haven’t provided a recording_url_resolver. Add one that returns the actual recording URL for each call.
  • If using LiveKit Egress, ensure the recording has finished processing before the resolver is called.

Webhooks

Tuner can notify your systems when it has something to report on a call — see Webhooks.

What’s Next?

Configuring Your Agent

Set up call outcomes, user intents, and evals.

Custom Integration

Learn about the underlying API if you need more control.

Classifying Calls

Define how Tuner categorizes your calls.

Real-Time Alerts

Get notified when issues are detected.