Overview
LiveKit connection enables integration with agents built on LiveKit’s real-time communication platform for audio, video, and data streaming. This connection type supports both LiveKit Cloud and self-hosted LiveKit deployments.Dispatch Modes
Whether your agent joins a Coval simulation’s room at all depends on how your LiveKit agent worker registers, not on your Coval configuration alone. LiveKit supports two dispatch modes:- Automatic dispatch (the default): If your worker calls
WorkerOptionswithout anagent_name, LiveKit auto-joins it to every new room created in your project. Most simple, single-agent setups use this mode, and no extra Coval configuration is needed. - Explicit dispatch: If your worker’s code passes an
agent_nametoWorkerOptions(LiveKit’s Python/Node agents SDK), it opts out of auto-join. It will only join a room when that room’s access token embeds the same name viaroom_config.agents[].agent_name.
livekit_agent_name, described below) to the exact same name your worker registered under. Once that field is set, Coval automatically builds the required room_config.agents[].agent_name payload and merges it into the request sent to your generate_token_endpoint—you don’t need to hand-author it in Custom Payload Fields.
Not sure which mode your agent uses? Check your own worker’s code for how it calls WorkerOptions:
- If it passes an
agent_nameargument, your agent uses explicit dispatch—set Coval’s Agent Name field to match. - If it doesn’t, your agent uses automatic dispatch and will auto-join Coval’s simulation rooms with no further configuration.
Configuration Requirements
Generate Token Endpoint
- Field:
generate_token_endpoint - Type: String (required)
- Purpose: Endpoint for generating LiveKit access tokens
- Format: Valid HTTPS URL
- Example:
https://your-api.com/livekit/token
livekit_agent_name), Coval merges a room_config key into that same request body:
room_config, room_name, and participant_name.
Your endpoint should return:
LiveKit URL
- Field:
livekit_url - Type: String (required)
- Purpose: LiveKit server WebSocket URL
- Format: Valid WebSocket URL (wss://)
- Example:
wss://your-livekit-server.com
If your token endpoint returns
serverUrl or server_url, that value will override this configuration.Generate Token Headers
- Field:
generate_token_headers - Type: String (optional)
- Purpose: HTTP headers for token generation requests
- Format: Valid JSON string
- Example:
{"X-Coval-Simulation-Id": "{{simulation_id}}"}
{{simulation_output_id}} and its {{simulation_id}} alias, plus {{test_case.*}}, {{agent.*}}, and {{run_metadata.*}} placeholders. Coval resolves them separately for each simulation before calling the token endpoint.
Sandbox ID (Development Token Server ID)
- Field:
sandbox_id - Type: String (optional, testing only)
- Purpose: Identifier for LiveKit Cloud’s hosted, dev-only token-minting API—what LiveKit’s own UI now labels the Development Token Server, formerly branded Sandbox
- When to use: If your
generate_token_endpointpoints at LiveKit’s hosted Sandbox/Development Token Server API rather than a backend you run yourself - When to skip: If you’re already running your own token-minting backend (LiveKit’s recommended production setup), skip this field entirely
“Sandbox” and “Development Token Server” are the same LiveKit mechanism, not two different features. LiveKit deprecated the standalone Sandbox product branding and now exposes the identical hosted token-minting API as a per-project Development Token Server toggle instead. Per LiveKit’s docs, “LiveKit Sandbox is deprecated, but the token server remains available as a standalone project setting”—and their own SDK reference still calls the parameter
sandboxId internally, since “API references to ‘Sandbox’ persist in SDKs due to historical naming.” If you already have a working sandbox_id, there’s nothing to migrate: it’s the same ID and the same hosted endpoint, just relabeled in LiveKit’s UI.This hosted API is fully functional today and remains a common way to get a LiveKit agent talking end-to-end during development—it is not an abandoned or removed feature. What’s genuinely deprecated is relying on it for production traffic; LiveKit still recommends it only for development and testing.How it’s actually called: the ID is sent as an X-Sandbox-ID HTTP header on requests to LiveKit’s hosted endpoint (cloud-api.livekit.io/api/v2/sandbox/connection-details)—it is not something you point a token endpoint at via the human-facing https://<id>.sandbox.livekit.io URL. That URL is a browser playground page (it returns 405/404 for direct API calls like POST / or POST /api/token), not a callable token-minting API. When Coval’s generate_token_endpoint is set to LiveKit’s hosted Sandbox/Development Token Server API, set this Sandbox ID field so Coval attaches the required X-Sandbox-ID header for you automatically.For testing and debugging your agent worker’s behavior (dispatch, joins, logs)—as opposed to token minting—LiveKit’s Agent Console remains the right tool, and it’s unrelated to this field. For production, run your own token-minting backend using LiveKit’s server SDK and point generate_token_endpoint at it—this has always been Coval’s recommended production setup, independent of Sandbox/Development Token Server history. See LiveKit’s deployment docs for more.LiveKit Agent Name
- Field:
livekit_agent_name - Type: String (optional)
- Purpose: Name identifier for the LiveKit agent
- Format: String identifier
- Example:
"voice-assistant","video-agent"
Custom Payload Fields
- Field:
token_request_payload - Type: String (optional)
- Purpose: Additional fields to include in the token request
- Format: Valid JSON string
- Example:
{"agent_variant": "sales", "language": "en"}
room_name and participant_name when calling your token endpoint.
Payload values support the same per-simulation placeholders as token request headers.
Setup Instructions
- Set up a token generation endpoint that accepts POST requests
- Configure your endpoint to return tokens with the correct room permissions
- Enter your LiveKit server WebSocket URL
- (Optional) Add authentication headers if your endpoint requires them
- Test the connection by launching a simulation
Sending Traces
Set Custom Headers (JSON) to{"X-Coval-Simulation-Id": "{{simulation_id}}"}. Coval replaces the placeholder before calling the token endpoint. Carry the header value into the agent’s dispatch context, then use it as X-Simulation-Id when exporting OpenTelemetry spans to Coval.
See OpenTelemetry Traces for the complete tracing setup.
Technical Details
Token Generation Flow
- Coval generates a unique room name (UUID) for each simulation
- Coval sends a POST request to your token endpoint with the room name
- Your endpoint generates a LiveKit JWT token with room access permissions
- Your endpoint should also dispatch your agent to join the same room
- Coval joins the room using the returned token
- Coval waits for your agent to join (
on_first_participant_joinedevent) - Conversation simulation begins
Accepted Response Field Names
Coval accepts multiple field name variations for flexibility:Troubleshooting
Common Issues
Token Generation Failures- Check endpoint accessibility and authentication
- Verify your endpoint returns valid JSON with a
tokenfield - Ensure HTTPS is properly configured
- Verify LiveKit server URL starts with
wss:// - Check that
serverUrlis included in your token response - Confirm your LiveKit server is running and accessible
- You’re using explicit dispatch (your worker registered with an
agent_name) but Coval’s Agent Name field is unset or doesn’t match. Setlivekit_agent_nameto the exact name your worker passed toWorkerOptions. - If Agent Name is set and matches, confirm your token endpoint actually embeds the incoming
room_configinto the minted token (e.g. viaRoomConfiguration/RoomAgentDispatch)—see Generate Token Endpoint. Receivingroom_configin the request isn’t enough; your endpoint must put it into the token itself, or dispatch will silently fail even though token generation succeeds. - Confirm the token response’s room name matches the room your worker actually expects to join.
- Check your worker’s logs for a dispatch request—if it never receives one, double-check the Agent Name value for typos.
- Ensure your agent dispatch system receives the
room_namefrom token requests - Verify your agent is running and connected to LiveKit
- Check that the token grants access to the correct room
- Coval waits for your agent to join before starting
- If your agent doesn’t join, the simulation will timeout
- Check your agent logs for connection errors
- Verify your response includes a recognized token field name
- Check that the token value is a non-empty string
- Ensure response Content-Type is
application/json
Running Components Locally
Coval’s servers need to reach your token endpoint and LiveKit server to run simulations. Here’s what needs to be publicly accessible:
If running your token server locally:
Use a tunneling service like ngrok to expose it:
Your agent can run on your local machine without any tunneling—it just connects outbound to the LiveKit server like any other client.