> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cekura.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Bulk Update Evaluators

> Bulk-update many evaluators in a single call: attach/detach metrics or tools, switch personality, append instructions, move into a folder, or change phone number / max duration.



## OpenAPI

````yaml post /test_framework/v1/scenarios/adv_update/
openapi: 3.1.0
info:
  title: Cekura API
  version: v1
  description: >-
    Complete API documentation for the Cekura platform. This API provides
    endpoints for testing, observing, and evaluating AI voice agents — including
    managing agents, running evaluators, defining metrics, and analyzing call
    quality.
servers:
  - url: https://api.cekura.ai
security: []
paths:
  /test_framework/v1/scenarios/adv_update/:
    post:
      tags:
        - Evaluators
      summary: Bulk update evaluators
      description: >-
        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.
      operationId: scenarios-bulk-update_2
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ScenariosBulkUpdateRequest'
            examples:
              AttachTwoMetricsToABatchOfScenarios:
                value:
                  agent: 12
                  scenarios:
                    - 101
                    - 102
                    - 103
                  metric_ids_to_add:
                    - 501
                    - 502
                summary: Attach two metrics to a batch of scenarios
              MoveScenariosIntoAFolderAndSwitchPersonality:
                value:
                  agent: 12
                  scenarios:
                    - 101
                    - 102
                  folder_path: Sales.Inbound
                  personality: 7
                summary: Move scenarios into a folder and switch personality
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/ScenariosBulkUpdateRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/ScenariosBulkUpdateRequest'
        required: true
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ScenarioList'
          description: ''
        '400':
          content:
            application/json:
              schema:
                type: object
                properties:
                  field_name:
                    type: array
                    items:
                      type: string
          description: ''
      security:
        - api_key: []
components:
  schemas:
    ScenariosBulkUpdateRequest:
      type: object
      properties:
        scenarios:
          type: array
          items:
            type: integer
          description: List of evaluator (scenario) IDs to update.
        agent:
          type: integer
          description: >-
            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:
          type: integer
          description: >-
            Scope the permission check to a specific project. Either this or
            `agent` is required.
        metric_ids_to_add:
          type: array
          items:
            type: integer
          description: Metric IDs to attach to each evaluator.
        metric_ids_to_remove:
          type: array
          items:
            type: integer
          description: Metric IDs to detach from each evaluator.
        tool_ids_to_add:
          type: array
          items:
            type: integer
          description: Tool IDs to attach to each evaluator.
        tool_ids_to_remove:
          type: array
          items:
            type: integer
          description: Tool IDs to detach from each evaluator.
        personality:
          type: integer
          description: Replace each evaluator's personality with this ID.
        test_profile:
          type: integer
          description: Replace each evaluator's test profile with this ID.
        append_instruction:
          type: string
          description: >-
            Text appended to every evaluator's instructions. Concatenates on
            each call — not idempotent.
        first_message:
          type: string
          description: Replace each evaluator's first message.
        phone_number:
          type: integer
          description: Replace each evaluator's outbound phone number ID.
        inbound_phone_number:
          type: integer
          description: Replace each evaluator's inbound phone number ID.
        folder_path:
          type: string
          description: >-
            Move every evaluator into this folder. Dot-separated (e.g.
            "Sales.Inbound").
        max_duration:
          type: integer
          description: Replace each evaluator's max duration in seconds.
      required:
        - scenarios
    ScenarioList:
      type: object
      description: ''
      properties:
        id:
          type: integer
          readOnly: true
          description: |

            Unique identifier for the AI agent
            Example: `123`
        name:
          type: string
          description: Name of the scenario
          maxLength: 80
        personality:
          type:
            - integer
            - 'null'
          description: Foreign key reference to the personality used in this scenario
        personality_name:
          type: string
          readOnly: true
          description: |

            Name of the personality used in this scenario
            Example: `"Normal Male"`
        agent_name:
          type: string
          readOnly: true
          description: |

            Name of the agent associated with this scenario
            Example: `"Customer Support Agent"`
        phone_number:
          type: string
          readOnly: true
        expected_outcome_prompt:
          type: string
          readOnly: true
          description: |

            Expected outcome prompt for the scenario
            Example: `"The user should be able to complete the order"`
        instructions:
          type: string
          description: >

            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 a JSON-formatted string with role and
            conditions:

            ```json

            {
              "role": "A friendly customer calling about an appointment",
              "conditions": [
                {
                  "id": 0,
                  "condition": "FIRST_MESSAGE",
                  "action": "Hi, I'd like to check on my upcoming appointment <silence time=\"1.5s\" />",
                  "type": "standard",
                  "fixed_message": true
                },
                {
                  "id": 1,
                  "condition": "The agent asks for your name",
                  "action": "My name is Sarah Johnson",
                  "type": "standard",
                  "fixed_message": true
                },
                {
                  "id": 2,
                  "condition": "The agent asks for your date of birth",
                  "action": "January first, nineteen ninety",
                  "type": "standard",
                  "fixed_message": true
                },
                {
                  "id": 3,
                  "condition": "The agent confirms your identity and provides appointment details",
                  "action": "Thank you, that's all I needed <silence time=\"1.0s\" />",
                  "type": "standard",
                  "fixed_message": true
                },
                {
                  "id": 4,
                  "condition": 3,
                  "action": "<endcall />",
                  "type": "action_followup",
                  "fixed_message": true
                }
              ]
            }

            ```


            **Structure:**

            - `role`: Personality/role description

            - `conditions`: Array with id (0,1,2...), condition (FIRST_MESSAGE |
            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 against the conversation context | integer
            reference to another condition's id), action (text with SSML
            `<silence time="1.5s" />` (interruptible) or `<hold time="2s" />`
            (not interruptible) and markers `[laughter]` or `<endcall />`), type
            (standard | action_followup), fixed_message (boolean)
        scenario_language:
          enum:
            - af
            - ar
            - bn
            - bg
            - zh
            - cs
            - da
            - nl
            - en
            - et
            - fi
            - fr
            - de
            - el
            - gu
            - hi
            - he
            - hu
            - id
            - it
            - ja
            - kn
            - ko
            - ms
            - ml
            - mr
            - multi
            - 'no'
            - pl
            - pa
            - pt
            - ro
            - ru
            - sk
            - es
            - sv
            - th
            - tr
            - tl
            - ta
            - te
            - uk
            - vi
            - null
          type:
            - string
            - 'null'
          x-spec-enum-id: b822ad429c7b7fec
          description: |-
            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
            * `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
            * `vi` - Vietnamese
        scenario_type:
          enum:
            - instruction
            - real_world_smart
            - real_world_fixed
            - conditional_actions
          type: string
          x-spec-enum-id: db62e37bb530b602
          default: instruction
          description: >-

            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

            - `real_world_smart`: Real world smart scenario

            - `real_world_fixed`: Real world fixed scenario



            * `instruction` - Instruction

            * `real_world_smart` - Real World Smart

            * `real_world_fixed` - Real World Fixed

            * `conditional_actions` - Conditional Actions
        tags:
          description: |

            List of tags associated with this scenario for categorization
            Example: `["tag1", "tag2", "tag3"]`
        agent:
          type: integer
          description: Foreign key reference to the AI agent that owns this scenario
        inbound_phone_number:
          type:
            - integer
            - 'null'
          description: >-
            (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:
          type: string
          readOnly: true
          description: Details of the phone number used for inbound calls
        metrics:
          type: string
          readOnly: true
          description: List of metrics associated with this scenario for evaluation
        metric_names:
          type: string
          readOnly: true
          description: |

            List of metric names associated with this scenario
            Example: `["Metric 1", "Metric 2", "Metric 3"]`
        first_message:
          type: string
          default: Hello
          description: >-
            The initial message that the AI agent will send when the scenario
            starts
        tool_ids:
          description: |

            List of tool IDs that are available for use in this scenario
            Example: `["TOOL_DTML", "TOOL_END_CALL"]`
        test_profile:
          type:
            - integer
            - 'null'
          description: |

            Test profile ID
            Example: `123`
        test_profile_data:
          allOf:
            - $ref: '#/components/schemas/AIAgentTestProfile'
          readOnly: true
          description: |

            Details of the test profile associated with this scenario
            Example:
            ```json
            {
                "id": "<integer>",
                "agent": "<integer>",
                "name": "<string>",
                "information": {
                    "user_name": "John Doe",
                    "user_email": "john.doe@example.com",
                }
            }
            ```
        dynamic_variable_values:
          oneOf:
            - {}
            - type: 'null'
          description: >-
            REMOVED FROM API. Historically stored a flat copy of the agent's
            dynamic-variable values for the scenario. The column is retained
            read-only for legacy rows; reads still return its historical value,
            but writes via the API are rejected with a 400. At call time the
            Run-level helper consults this column ONLY when the attached
            test_profile is legacy-flat (or absent) — sectioned test profiles
            are the canonical source and ignore this column. Put
            dynamic-variable values in
            `test_profile.information.main_agent_variables` for new scenarios.
        created_at:
          type: string
          format: date-time
          readOnly: true
          description: Timestamp when the scenario was created
        updated_at:
          type: string
          format: date-time
          readOnly: true
          description: Timestamp when the scenario was last updated
        created_by:
          type: integer
          readOnly: true
          description: ID of the user who created this scenario
        last_updated_by:
          type: integer
          readOnly: true
          description: ID of the user who last updated this scenario
        folder_path:
          type:
            - string
            - 'null'
            - 'null'
          description: >-
            Dot-separated path of the folder to assign this evaluator to (e.g.
            "Sales.Inbound"). Folders must be created before use — they are not
            auto-created. Use `scenarios_create_folder_create` to create each
            level before assigning evaluators. Example: to use "Sales.Inbound",
            first create "Sales", then create "Inbound" inside it.
      required:
        - agent
        - instructions
        - name
    AIAgentTestProfile:
      type: object
      description: ''
      properties:
        id:
          type: integer
          readOnly: true
        project:
          type:
            - integer
            - 'null'
        agent:
          type:
            - integer
            - 'null'
        agent_name:
          type: string
          readOnly: true
          description: |

            Name of the agent associated with this test profile
            Example: `"Customer Support Agent"`
        name:
          type: string
          maxLength: 255
        information:
          description: >

            Variables for the test profile, split by which agent receives them.

            ```json

            {
                "main_agent_variables": {"user_id": "U-123"},
                "testing_agent_variables": {"user_name": "John Doe", "user_email": "john.doe@example.com"}
            }

            ```

            `main_agent_variables` are sent to the agent under test as dynamic
            variables. `testing_agent_variables` shape the simulated caller's
            persona. A legacy flat dict (no section keys) is accepted for
            backward compatibility and is sent to both agents.


            Keys in `main_agent_variables` starting with `X-` are additionally
            sent as custom SIP headers (SIP runs) or connection headers
            (WebSocket runs) to the agent under test. For SIP runs this is the
            only way to pass custom headers; `X-Run-Id`, `X-Scenario-Id`, and
            `X-Result-Id` are reserved and always set by Cekura.
        created_by:
          type: integer
          readOnly: true
          description: ID of the user who created this test profile
        last_updated_by:
          type: integer
          readOnly: true
          description: ID of the user who last updated this test profile
        created_at:
          type: string
          format: date-time
          readOnly: true
          description: Timestamp when the test profile was created
        updated_at:
          type: string
          format: date-time
          readOnly: true
          description: Timestamp when the test profile was last updated
      required:
        - name
  securitySchemes:
    api_key:
      type: apiKey
      name: X-CEKURA-API-KEY
      in: header
      description: >-
        API Key Authentication. It should be included in the header of each
        request.

````