curl --request GET \
--url https://api.cekura.ai/test_framework/v1/scenarios/{id}/ \
--header 'X-CEKURA-API-KEY: <api-key>'import requests
url = "https://api.cekura.ai/test_framework/v1/scenarios/{id}/"
headers = {"X-CEKURA-API-KEY": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {'X-CEKURA-API-KEY': '<api-key>'}};
fetch('https://api.cekura.ai/test_framework/v1/scenarios/{id}/', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.cekura.ai/test_framework/v1/scenarios/{id}/",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"X-CEKURA-API-KEY: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.cekura.ai/test_framework/v1/scenarios/{id}/"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("X-CEKURA-API-KEY", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.cekura.ai/test_framework/v1/scenarios/{id}/")
.header("X-CEKURA-API-KEY", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.cekura.ai/test_framework/v1/scenarios/{id}/")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["X-CEKURA-API-KEY"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"id": 123,
"name": "<string>",
"agent": 123,
"project": 123,
"personality": 123,
"personality_name": "<string>",
"agent_name": "<string>",
"tags": [
"<string>"
],
"tool_ids": "<unknown>",
"metrics": [
123
],
"metric_names": [
"<string>"
],
"phone_number": "<string>",
"outbound_phone_number_data": {
"number": "<string>",
"phone_number_id": "<string>",
"id": 123
},
"first_message": "<string>",
"inbound_phone_number": 123,
"inbound_phone_number_data": {
"number": "<string>",
"phone_number_id": "<string>",
"id": 123
},
"instructions": "<string>",
"condition_audio": {},
"simulation_description": "<string>",
"information_fields": {},
"expected_outcome_prompt": "<string>",
"scenario_language": "af",
"scenario_type": "<string>",
"suite_type": "undefined",
"is_predefined": true,
"test_profile": 123,
"test_profile_data": {
"name": "<string>",
"id": 123,
"project": 123,
"agent": 123,
"agent_name": "<string>",
"information": "<unknown>",
"created_by": 123,
"last_updated_by": 123,
"created_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z"
},
"dynamic_variable_values": "<unknown>",
"generated_mock_tool_entries": "<unknown>",
"folder_path": "<string>",
"max_duration": 123
}{
"detail": "<string>"
}Get Evaluator
Retrieve a test scenario by ID
curl --request GET \
--url https://api.cekura.ai/test_framework/v1/scenarios/{id}/ \
--header 'X-CEKURA-API-KEY: <api-key>'import requests
url = "https://api.cekura.ai/test_framework/v1/scenarios/{id}/"
headers = {"X-CEKURA-API-KEY": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {'X-CEKURA-API-KEY': '<api-key>'}};
fetch('https://api.cekura.ai/test_framework/v1/scenarios/{id}/', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.cekura.ai/test_framework/v1/scenarios/{id}/",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"X-CEKURA-API-KEY: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.cekura.ai/test_framework/v1/scenarios/{id}/"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("X-CEKURA-API-KEY", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.cekura.ai/test_framework/v1/scenarios/{id}/")
.header("X-CEKURA-API-KEY", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.cekura.ai/test_framework/v1/scenarios/{id}/")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["X-CEKURA-API-KEY"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"id": 123,
"name": "<string>",
"agent": 123,
"project": 123,
"personality": 123,
"personality_name": "<string>",
"agent_name": "<string>",
"tags": [
"<string>"
],
"tool_ids": "<unknown>",
"metrics": [
123
],
"metric_names": [
"<string>"
],
"phone_number": "<string>",
"outbound_phone_number_data": {
"number": "<string>",
"phone_number_id": "<string>",
"id": 123
},
"first_message": "<string>",
"inbound_phone_number": 123,
"inbound_phone_number_data": {
"number": "<string>",
"phone_number_id": "<string>",
"id": 123
},
"instructions": "<string>",
"condition_audio": {},
"simulation_description": "<string>",
"information_fields": {},
"expected_outcome_prompt": "<string>",
"scenario_language": "af",
"scenario_type": "<string>",
"suite_type": "undefined",
"is_predefined": true,
"test_profile": 123,
"test_profile_data": {
"name": "<string>",
"id": 123,
"project": 123,
"agent": 123,
"agent_name": "<string>",
"information": "<unknown>",
"created_by": 123,
"last_updated_by": 123,
"created_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z"
},
"dynamic_variable_values": "<unknown>",
"generated_mock_tool_entries": "<unknown>",
"folder_path": "<string>",
"max_duration": 123
}{
"detail": "<string>"
}Authorizations
API Key Authentication. It should be included in the header of each request.
Path Parameters
A unique integer value identifying this scenario.
Query Parameters
Set to legacy to return conditional-action instructions in the earlier id-based format (id, condition, action, type, fixed_message).
legacy Response
Name of the evaluator
Agent ID
Example: 2142
ID of the personality
Name of the personality
Name of the agent associated with this scenario
Example: "Customer Support Agent"
List of tags of the evaluators
Example: ["tag1", "tag2", "tag3"]
List of tool IDs to associate with this scenario
Example: ["TOOL_DTMF", "TOOL_END_CALL"]
List of metric IDs
Example: [123, 456, 789]
List of metric names
Example: ["Metric 1", "Metric 2", "Metric 3"]
Phone number eg: +17776666333
Phone number used for outbound calls in this scenario
Example: "+1234567890"
Show child attributes
Show child attributes
First message of the evaluator
(Deprecated) Phone number used for inbound calls in this scenario. Use outbound_phone_number_data instead.
After CEK-6517, both phone_number and inbound_phone_number fields are synced, so outbound_phone_number_data contains the unified phone number for both inbound and outbound calls.
Example: {"id": 123, "number": "+1234567890", "phone_number_id": "abc123"}
Show child attributes
Show child attributes
Scenario Instructions - format depends on scenario_type:
- For
instructiontype: Plain text instructions - For
conditional_actionstype: JSON string withrole,first_messageand aconditionsarray. Each condition haswhen(a natural-language third-person description of the main agent's observable action — e.g."The agent asks for your date of birth", matched semantically),say(spoken verbatim, with optional<silence time="1.5s" />(interruptible) or<hold time="2s" />(not interruptible) and[laughter]tags; wrap the whole step in<ai_generated>...</ai_generated>to improvise instead) and optionalthenfollow-up steps. Responses return this format unlessconditional_actions_format=legacyis passed. The earlier id-based format (id,condition,action,type,fixed_message) is still accepted on writes.
Pre-recorded clips available to this scenario's conditional actions, keyed by clip id. Read-only: upload and delete clips through condition-audio/. Reference a clip from any number of verbatim steps by pasting its tag; steps lists where it is used (e.g. conditions[1].then[0]).
Example:
{
"greeting": {"tag": "<audio id=\"greeting\"/>", "filename": "greeting.wav",
"status": "ready", "duration": 2.4, "transcript": "Hi, is this the clinic?",
"steps": ["first_message", "conditions[1]"]}
}
Show child attributes
Show child attributes
Information fields of the evaluator Example:
{
"user_name": "John Doe",
"user_email": "john.doe@example.com",
}
Show child attributes
Show child attributes
Expected outcome prompt of the evaluator
Example: "The user should be able to complete the order"
Language of the scenario
af- Afrikaansar- Arabicbn- Bengalibg- Bulgarianzh- Chinese Simplifiedcs- Czechda- Danishnl- Dutchen- Englishet- Estonianfi- Finnishfr- Frenchde- Germanel- Greekgu- Gujaratihi- Hindihe- Hebrewhu- Hungarianid- Indonesianit- Italianja- Japanesekn- Kannadakk- Kazakhko- Koreanms- Malayml- Malayalammr- Marathimulti- Multilingualno- Norwegianpl- Polishpa- Punjabipt- Portuguesero- Romanianru- Russiansk- Slovakes- Spanishsv- Swedishth- Thaitr- Turkishtl- Tagalogta- Tamilte- Teluguuk- Ukrainianuz- Uzbekvi- Vietnamese
af, ar, bn, bg, zh, cs, da, nl, en, et, fi, fr, de, el, gu, hi, he, hu, id, it, ja, kn, kk, ko, ms, ml, mr, multi, no, pl, pa, pt, ro, ru, sk, es, sv, th, tr, tl, ta, te, uk, uz, vi Type of scenario:
instruction: Standard instruction-based scenario (plain text instructions)conditional_actions: Conditional action-based scenario (JSON with role, conditions, SSML tags, emotion markers)
Type of predefined suite (e.g., infrastructure)
undefined- Undefinedinfrastructure- Infrastructure
undefined, infrastructure Whether this is a predefined scenario (template)
Details of the test profile associated with this scenario. information uses the
sectioned shape: main_agent_variables are sent to the agent under test as
dynamic variables at call time; testing_agent_variables are persona/context
used by Cekura's simulated caller. Legacy flat dicts (no section keys) still
work — at call time they are delivered to both sides for backward compatibility.
Example:
{
"id": "<integer>",
"agent_id": "<integer>",
"name": "<string>",
"information": {
"main_agent_variables": {
"user_id": "<string>",
"account_id": "<string>"
},
"testing_agent_variables": {
"user_name": "<string>",
"user_email": "<string>",
"order_id": "<string>"
}
}
}
Show child attributes
Show child attributes
REMOVED FROM API. Reads return the historical value for legacy rows (null for new rows). Writes are no longer accepted — supplying a non-null value yields a 400 error. Put dynamic-variable values in test_profile_data.information.main_agent_variables instead: create the test profile via POST /test-profiles/ and attach it via the test_profile field on the scenario.
Expected mock tool calls for this evaluator. Each entry has shape {tool_id, tool_name, new_entry: {input, output, response?}}. Auto-generated during scenario generation when the agent has mock tools attached; can also be set or edited manually.
Path of an existing folder to assign this evaluator to, e.g. "Sales" or "Sales.Inbound". Create it first with the create-folder endpoint.
Max call duration in seconds for this scenario. If not provided or set to null, the scenario will use the project's max_call_duration setting.
Valid range: 10-3600 seconds (10 seconds to 60 minutes)
Example: 600 (10 minutes)