---
title: "Bulk update evaluators"
method: POST
path: "/test_framework/v1/scenarios/adv_update/"
tags: ["Evaluators"]
---

# Bulk update evaluators

`POST /test_framework/v1/scenarios/adv_update/`

## Request

- Base URL: `https://api.cekura.ai`
- URL: `https://api.cekura.ai/test_framework/v1/scenarios/adv_update/`
- Auth: one of:
  - API key in header `X-CEKURA-API-KEY`
  - HTTP bearer
  - HTTP bearer

Update many evaluators in a single call. Useful for attaching/detaching metrics, switching personality, appending instructions, or moving a batch between folders.

**Non-idempotent fields:** `append_instruction` concatenates — calling twice with the same string adds it twice. `metric_ids_to_add`/`metric_ids_to_remove` and `tool_ids_to_add`/`tool_ids_to_remove` are set-mutating and shouldn't be replayed blindly.

**Affects every ID in `scenarios`.** For modifying a single evaluator, prefer `scenarios_partial_update`. Confirm the `scenarios` list with the user before calling — the change is applied across the whole list in one transaction.

**Required:** `scenarios` (list of evaluator IDs). One of `agent` or `project` is also required to scope the permission check. All other fields are optional and are applied only when present.

## Request body

- ScenariosBulkUpdateRequest
  - `scenarios` integer[], required: List of evaluator (scenario) IDs to update.
  - `agent` integer: Scopes the permission check to a specific agent (either this or `project` is required). When provided, also overrides each evaluator's `agent` to this ID.
  - `project` integer: Scope the permission check to a specific project. Either this or `agent` is required.
  - `metric_ids_to_add` integer[]: Metric IDs to attach to each evaluator.
  - `metric_ids_to_remove` integer[]: Metric IDs to detach from each evaluator.
  - `tool_ids_to_add` integer[]: Tool IDs to attach to each evaluator.
  - `tool_ids_to_remove` integer[]: Tool IDs to detach from each evaluator.
  - `personality` integer: Replace each evaluator's personality with this ID.
  - `test_profile` integer: Replace each evaluator's test profile with this ID.
  - `append_instruction` string: Text appended to every evaluator's instructions. Concatenates on each call — not idempotent.
  - `first_message` string: Replace each evaluator's first message.
  - `phone_number` integer: Replace each evaluator's outbound phone number ID.
  - `inbound_phone_number` integer: Replace each evaluator's inbound phone number ID.
  - `folder_path` string: Move every evaluator into this folder. Dot-separated (e.g. "Sales.Inbound").
  - `max_duration` integer: Replace each evaluator's max duration in seconds.

## Response `200`

- ScenarioList
  - `id` integer: Unique identifier for the AI agent Example: `123`
  - `name` string, required: Name of the scenario
  - `personality` integer, nullable: Foreign key reference to the personality used in this scenario
  - `personality_name` string: Name of the personality used in this scenario Example: `"Normal Male"`
  - `agent_name` string: Name of the agent associated with this scenario Example: `"Customer Support Agent"`
  - `phone_number` string
  - `expected_outcome_prompt` string: Expected outcome prompt for the scenario Example: `"The user should be able to complete the order"`
  - `instructions` string, required: Scenario Instructions - format depends on scenario_type: **For scenario_type="instruction":** Plain text describing the caller's behavior. Example: `"You are a customer calling to inquire about your order status. Be polite and provide order number 12345 when asked."` **For scenario_type="conditional_actions":** Use the structured `conditional_actions` field instead. If you must send via this field, pass the same object as a JSON-formatted string. The earlier id-based format (`id`, `condition`, `action`, `type`, `fixed_message`) is still accepted on writes. Responses return this shape unless `conditional_actions_format=legacy` is passed: ```json { "role": "A friendly customer calling about an appointment", "first_message": "Hi, I'd like to check on my upcoming appointment <silence time=\"1.5s\" />", "conditions": [ {"when": "The agent asks for your name", "say": "My name is Sarah Johnson"}, {"when": "The agent asks for your date of birth", "say": "January first, nineteen ninety"}, { "when": "The agent confirms your identity and provides appointment details", "say": "Thank you, that's all I needed", "then": ["<endcall />"] } ] } ``` **Structure:** - `role`: Personality/role description - `first_message`: What the caller says first; empty means wait for the agent. Use `{"say": "...", "then": [...]}` to add follow-ups. - `conditions[].when`: A third-person description of the agent's observable action, matched semantically against the conversation - `conditions[].say`: The caller's reply, spoken verbatim. Wrap the whole step in `<ai_generated>...</ai_generated>` to let the caller improvise from it instead - `conditions[].then`: Optional follow-up steps, each fired on the caller's next turn after one agent reply, in order - Steps support SSML `<silence time="1.5s" />` (interruptible), `<hold time="2s" />` (not interruptible), `[laughter]` and `<endcall />` in verbatim steps
  - `scenario_language` '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' | 'null', nullable: Language code for the scenario (ISO language code) * `af` - Afrikaans * `ar` - Arabic * `bn` - Bengali * `bg` - Bulgarian * `zh` - Chinese Simplified * `cs` - Czech * `da` - Danish * `nl` - Dutch * `en` - English * `et` - Estonian * `fi` - Finnish * `fr` - French * `de` - German * `el` - Greek * `gu` - Gujarati * `hi` - Hindi * `he` - Hebrew * `hu` - Hungarian * `id` - Indonesian * `it` - Italian * `ja` - Japanese * `kn` - Kannada * `kk` - Kazakh * `ko` - Korean * `ms` - Malay * `ml` - Malayalam * `mr` - Marathi * `multi` - Multilingual * `no` - Norwegian * `pl` - Polish * `pa` - Punjabi * `pt` - Portuguese * `ro` - Romanian * `ru` - Russian * `sk` - Slovak * `es` - Spanish * `sv` - Swedish * `th` - Thai * `tr` - Turkish * `tl` - Tagalog * `ta` - Tamil * `te` - Telugu * `uk` - Ukrainian * `uz` - Uzbek * `vi` - Vietnamese
  - `scenario_type` 'instruction' | 'conditional_actions': Type of scenario: - `instruction`: Standard instruction-based scenario where instructions field contains plain text - `conditional_actions`: Conditional action-based scenario where instructions field contains JSON * `instruction` - Instruction * `conditional_actions` - Conditional Actions
  - `tags` unknown
  - `agent` integer, required: Foreign key reference to the AI agent that owns this scenario
  - `inbound_phone_number` integer, nullable: (Deprecated) Foreign key reference to the phone number. Use phone_number field instead. This field is maintained for backward compatibility and will be automatically synced with phone_number.
  - `inbound_phone_number_data` string: Details of the phone number used for inbound calls
  - `metrics` string: List of metrics associated with this scenario for evaluation
  - `metric_names` string: List of metric names associated with this scenario Example: `["Metric 1", "Metric 2", "Metric 3"]`
  - `first_message` string: The initial message that the AI agent will send when the scenario starts
  - `tool_ids` unknown
  - `test_profile` integer, nullable: Test profile ID Example: `123`
  - `test_profile_data` AIAgentTestProfile
    - `id` integer
    - `project` integer, nullable
    - `agent` integer, nullable
    - `agent_name` string: Name of the agent associated with this test profile Example: `"Customer Support Agent"`
    - `name` string, required
    - `information` unknown
    - `created_by` integer, nullable: ID of the user who created this test profile
    - `last_updated_by` integer, nullable: ID of the user who last updated this test profile
    - `created_at` string, date-time: Timestamp when the test profile was created
    - `updated_at` string, date-time: Timestamp when the test profile was last updated
  - `dynamic_variable_values` unknown
  - `created_at` string, date-time: Timestamp when the scenario was created
  - `updated_at` string, date-time: Timestamp when the scenario was last updated
  - `created_by` integer, nullable: ID of the user who created this scenario
  - `last_updated_by` integer, nullable: ID of the user who last updated this scenario
  - `folder_path` string, nullable: Path of an existing folder to assign this evaluator to, e.g. "Sales" or "Sales.Inbound". Create it first with the create-folder endpoint.

## Other responses

- `400`

## Changes

- **2026-11-03** `a6fb6a739212`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/cekura/apis/cekura-api/changes/test_framework/v1/scenarios/adv_update/post.md)

---

[API](https://skmtc.dev/cekura/apis/cekura-api.md) - [All operations](https://skmtc.dev/cekura/apis/cekura-api/llms.txt) - [OpenAPI document](https://skmtc.dev/cekura/apis/cekura-api/revisions/a6fb6a739212?raw)
