Skip to main content

Overview

Use this flow to test your agent by joining a LiveKit room via WebRTC for each evaluator run. Each item you submit will create a run that connects using your provided LiveKit room URL and access token. This page covers both voice and chat (text mode) flows.
Each array element you send creates a separate run. To run the same scenario multiple times in parallel, repeat that scenario object multiple times in the payload.

Prerequisites

  • A Cekura account
  • One or more scenarios created for your agent
  • LiveKit room URL and a valid access token for each run you intend to start

API Endpoint

  • Method: POST
  • URL: https://api.cekura.ai/test_framework/v1/scenarios-external/run_scenarios_livekit/
  • Headers:
    • X-CEKURA-API-KEY: your API key
    • Content-Type: application/json

Request Body

  • scenarios: Array of objects. Each object fields:
    • scenario (number, required): Scenario ID
    • livekit_room_url (string, required): Your LiveKit room URL
    • access_token (string, required): LiveKit access token

Example: Minimal Single Run (cURL)

curl -X POST \
  'https://api.cekura.ai/test_framework/v1/scenarios-external/run_scenarios_livekit/' \
  -H 'X-CEKURA-API-KEY: <YOUR_API_KEY>' \
  -H 'Content-Type: application/json' \
  -d '{
    "scenarios": [
      {
        "scenario": 30,
        "livekit_room_url": "wss://<LK_ROOM_URL>",
        "access_token": "<LK_TOKEN>"
      }
    ]
  }'

Example: Multiple Runs (JSON)

{
  "scenarios": [
    {
      "scenario": 30,
      "livekit_room_url": "wss://<LK_ROOM_URL>",
      "access_token": "<LK_TOKEN_1>"
    },
    {
      "scenario": 31,
      "livekit_room_url": "wss://<LK_ROOM_URL>",
      "access_token": "<LK_TOKEN_2>"
    }
  ]
}

Example: Python

import requests

API_KEY = "<YOUR_API_KEY>"
BASE_URL = "https://api.cekura.ai/test_framework"

headers = {
    "X-CEKURA-API-KEY": API_KEY,
    "Content-Type": "application/json",
}

payload = {
    "scenarios": [
        {
            "scenario": 30,
            "livekit_room_url": "wss://<LK_ROOM_URL>",
            "access_token": "<LK_TOKEN_1>",
        },
        {
            "scenario": 31,
            "livekit_room_url": "wss://<LK_ROOM_URL>",
            "access_token": "<LK_TOKEN_2>",
        },
    ]
}

resp = requests.post(
    f"{BASE_URL}/v1/scenarios-external/run_scenarios_livekit/",
    headers=headers,
    json=payload,
)
result = resp.json()
print(result)

Expected Behavior

  • A result is created and a run is queued for each item in scenarios
  • Each run connects to the provided LiveKit room URL using the given access token
  • You can poll run statuses using the Bulk Runs API:

API Reference

Get Runs with IDs: API Doc

Chat Flow (Text Mode)

Use this endpoint to test your LiveKit agent using text-based chat instead of voice. The same manual approach applies (you provide room URL and token), but the evaluator communicates via data messages rather than audio.

Dispatching Your Agent for Chat Mode

If you have tracing enabled, you can send text_mode: true in the agent dispatch metadata and the tracer will handle text mode automatically:
from livekit.api import LiveKitAPI, CreateAgentDispatchRequest
import json

livekit_api = LiveKitAPI(
    url="wss://<YOUR_LIVEKIT_URL>",
    api_key="<YOUR_API_KEY>",
    api_secret="<YOUR_API_SECRET>",
)

dispatch_metadata = {
    "text_mode": True,
    # ... any other metadata your agent needs
}

await livekit_api.agent_dispatch.create_dispatch(
    CreateAgentDispatchRequest(
        agent_name="your-agent-name",
        room="your-room-name",
        metadata=json.dumps(dispatch_metadata),
    )
)
If you do not have tracing enabled, you must ensure your agent can operate in an LLM-only mode (without STT/TTS) and handle text-based data messages directly.

API Endpoint

  • Method: POST
  • URL: https://api.cekura.ai/test_framework/v1/scenarios-external/run_scenarios_livekit_chat/
  • Headers:
    • X-CEKURA-API-KEY: your API key
    • Content-Type: application/json

Request Body

  • scenarios: Array of objects. Each object fields:
    • scenario (number, required): Scenario ID
    • livekit_room_url (string, required): Your LiveKit room URL
    • access_token (string, required): LiveKit access token
    • publish_data_message (object, optional): Additional data message payload
  • agent (number, optional): Agent ID. Not required if scenarios already have agents assigned.

Example: cURL

curl -X POST \
  'https://api.cekura.ai/test_framework/v1/scenarios-external/run_scenarios_livekit_chat/' \
  -H 'X-CEKURA-API-KEY: <YOUR_API_KEY>' \
  -H 'Content-Type: application/json' \
  -d '{
    "scenarios": [
      {
        "scenario": 30,
        "livekit_room_url": "wss://<LK_ROOM_URL>",
        "access_token": "<LK_TOKEN>"
      }
    ]
  }'

Example: Python

import requests

API_KEY = "<YOUR_API_KEY>"
BASE_URL = "https://api.cekura.ai/test_framework"

headers = {
    "X-CEKURA-API-KEY": API_KEY,
    "Content-Type": "application/json",
}

payload = {
    "scenarios": [
        {
            "scenario": 30,
            "livekit_room_url": "wss://<LK_ROOM_URL>",
            "access_token": "<LK_TOKEN>",
        },
    ],
}

resp = requests.post(
    f"{BASE_URL}/v1/scenarios-external/run_scenarios_livekit_chat/",
    headers=headers,
    json=payload,
)
result = resp.json()
print(result)

Expected Behavior

  • A result is created and a run is queued for each item in scenarios
  • Each run connects to the provided LiveKit room and communicates via text data messages
  • The webhook flow works the same as voice — Cekura matches the webhook transcript to the run using similarity matching and temporal alignment

Billing

Chat runs are billed at text simulation rates, not voice simulation rates.

Troubleshooting

  • 401/403 errors: Check your X-CEKURA-API-KEY
  • Room connection failures: Verify livekit_room_url and access_token
  • No runs created: Ensure the scenarios array is not empty and scenario IDs are valid
  • Chat messages not received: Ensure your agent was dispatched with text_mode: true in dispatch metadata
For detailed LiveKit traces and observability, check out the LiveKit Tracing documentation.

Next Steps