> ## 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.

# Create Metric

> Create a quality metric for evaluating agent conversations.



## OpenAPI

````yaml post /test_framework/v2/metrics/
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/v2/metrics/:
    post:
      tags:
        - Metrics
      summary: Create a metric
      description: >-
        Create a quality metric. `type` is `llm_judge` or `custom_code`.
        `eval_type` is one of `binary`, `continuous_qualitative`, `numeric`,
        `enum`. Set `add_to_rubric=true` to include the metric in the project's
        call-success rubric.
      operationId: metrics-create
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/MetricEditSerializerV2'
            examples:
              LLMJudgeMetric(simplest—MostCommon):
                value:
                  project: 1376
                  name: Was the caller greeted by name
                  description: >-
                    Score TRUE if the agent addressed the caller by their name
                    within the first 3 turns, FALSE otherwise.
                  type: llm_judge
                  eval_type: bool
                  simulation_enabled: true
                  observability_enabled: true
                summary: LLM judge metric (simplest — most common)
              LLMJudge—EnumOutput:
                value:
                  project: 1376
                  name: Call resolution outcome
                  description: >-
                    Classify how the call ended: `resolved` (caller's issue was
                    fully addressed), `transferred` (caller was handed off to a
                    human), `dropped` (caller hung up without resolution).
                  type: llm_judge
                  eval_type: enum
                  enum_values:
                    - resolved
                    - transferred
                    - dropped
                  observability_enabled: true
                summary: LLM judge — enum output
              CustomCodeMetric(deterministicCheck):
                value:
                  project: 1376
                  name: Agent asked for order ID before refund
                  type: custom_code
                  eval_type: bool
                  custom_code: |
                    def score(transcript, context):
                        text = transcript.lower()
                        return 'order id' in text[:text.find('refund')] if 'refund' in text else True
                  simulation_enabled: true
                summary: Custom code metric (deterministic check)
              BinaryLLM-judgeMetric(addedToRubric):
                value:
                  name: Agent greeted the customer
                  description: >-
                    Check if the agent greeted the customer at the start of the
                    call.
                  project: 42
                  type: llm_judge
                  eval_type: binary
                  evaluation_trigger: always
                  add_to_rubric: true
                summary: Binary LLM-judge metric (added to rubric)
              ContinuousLLM-judgeMetric(0–5Rubric):
                value:
                  name: Empathy level
                  description: Rate how empathetic the agent was on a 0–5 scale.
                  project: 42
                  type: llm_judge
                  eval_type: continuous_qualitative
                  evaluation_trigger: always
                summary: Continuous LLM-judge metric (0–5 rubric)
              NumericCustom-codeMetric:
                value:
                  name: Words per minute
                  description: Compute the agent's speaking rate.
                  project: 42
                  type: custom_code
                  eval_type: numeric
                  custom_code: |-
                    def evaluate(transcript):
                        return {'score': len(transcript.split()) / max(1, transcript_duration_minutes)}
                  evaluation_trigger: always
                summary: Numeric custom-code metric
              EnumLLM-judgeMetric:
                value:
                  name: Call outcome
                  description: >-
                    Classify the call outcome as one of: booked, follow_up,
                    declined.
                  project: 42
                  type: llm_judge
                  eval_type: enum
                  enum_values:
                    - booked
                    - follow_up
                    - declined
                  evaluation_trigger: always
                summary: Enum LLM-judge metric
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/MetricEditSerializerV2'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/MetricEditSerializerV2'
        required: true
      responses:
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MetricDetailSerializerV2'
          description: ''
        '400':
          content:
            application/json:
              schema:
                type: object
                properties:
                  field_name:
                    type: array
                    items:
                      type: string
          description: ''
      security:
        - api_key: []
components:
  schemas:
    MetricEditSerializerV2:
      type: object
      properties:
        id:
          type: integer
          readOnly: true
        slug:
          type:
            - string
            - 'null'
          description: URL-friendly unique identifier in snake_case format
          maxLength: 255
        project:
          type:
            - integer
            - 'null'
        agent:
          type:
            - integer
            - 'null'
        agents:
          type: array
          items:
            type:
              - integer
              - 'null'
        assistant_id:
          type: string
          writeOnly: true
        name:
          type: string
          description: |-

            Name of the metric.
            Example: `"Customer Satisfaction"` or `"Appointment Booking"`
                    
          maxLength: 255
        description:
          type: string
          description: >-

            Description of what the metric measures.

            Example: `"Measures how satisfied customers are with the service
            provided"`
                    
        type:
          enum:
            - basic
            - custom_prompt
            - custom_code
            - llm_judge
          type: string
          x-spec-enum-id: b44700c0a6443b40
          description: >-

            Type of metric



            * `basic` - Basic (Deprecated in favor of LLM Judge)

            * `custom_prompt` - Custom Prompt ( Deprecated in favor of LLM
            Judge)

            * `custom_code` - Custom Code

            * `llm_judge` - LLM Judge
        eval_type:
          enum:
            - binary
            - continuous_qualitative
            - numeric
            - enum
          type: string
          description: |-
            * `binary` - Binary
            * `continuous_qualitative` - Continuous Qualitative
            * `numeric` - Numeric
            * `enum` - Enum
          x-spec-enum-id: b40eac6824409cc2
        audio_enabled:
          type: boolean
          readOnly: true
          description: |-

            Whether this metric requires audio analysis.
            Example: `true` or `false`
                    
        observability_enabled:
          type: boolean
          description: |-

            Enable this metric for observability.
            Example: `true` or `false`
                    
        simulation_enabled:
          type: boolean
          description: |-

            Enable this metric for simulations.
            Example: `true` or `false`
                    
        sampling_enabled:
          type: boolean
          description: Enable sampling for this metric using project-level sample rate
        prompt:
          type: string
          description: |

            Evaluation prompt for the metric.
            Example: `"Evaluate customer satisfaction based on conversation"`
        function_name:
          type:
            - string
            - 'null'
          readOnly: true
          description: |

            Predefined function name
            Example: `"get_latency"` or `"check_critical_deviations"`
        enum_values:
          type: array
          items:
            type: string
        display_order:
          type: integer
          maximum: 2147483647
          minimum: -2147483648
          description: |

            Display order for the metric.
            Example: `1`
        custom_code:
          type: string
          description: >

            Python custom code for the metric.

            Example:

            ```python

            _resul = True

            _explanation = None

            if  "call_end_reason" in data and data["call_end_reason"] ==
            "customer_satisfaction":
                _result = True
                _explanation = "Customer expressed satisfaction with service"
            ```
        evaluation_trigger:
          enum:
            - always
            - automatic
            - custom
          type: string
          description: |-
            * `always` - Always
            * `automatic` - Automatic
            * `custom` - Custom
          x-spec-enum-id: ecd3c02e0e393ef5
        trigger_type:
          enum:
            - llm_judge
            - custom_code
          type: string
          description: |-
            * `llm_judge` - LLM Judge
            * `custom_code` - Custom Code
          x-spec-enum-id: 2adad4b8df61914f
        evaluation_trigger_prompt:
          type: string
          description: >

            Evaluation trigger prompt for the metric.

            Example: `"Evaluate metric only if call ended reason is
            main-agent-ended-call"`
        evaluation_trigger_custom_code:
          type: string
          description: >

            Python custom code to determine metric relevance. Code should set
            _result (bool) and _explanation (str).

            Example:

            ```python

            _result = True

            _explanation = "Metric is relevant"

            if "call_end_reason" in data and data["call_end_reason"] ==
            "customer-hung-up":
                _result = False
                _explanation = "Customer hung up, metric not applicable"
            ```
        llm_provider:
          enum:
            - openai
            - gemini
            - dspy-gepa-gemini-flash
            - deepseek-v4-flash
          type: string
          description: |-
            * `openai` - OpenAI
            * `gemini` - Gemini
            * `dspy-gepa-gemini-flash` - Dspy Gepa Gemini Flash
            * `deepseek-v4-flash` - DeepSeek V4 Flash
          x-spec-enum-id: 6d1d2e77c71d1721
          writeOnly: true
        relevance_llm_provider:
          enum:
            - openai
            - gemini
            - dspy-gepa-gemini-flash
            - deepseek-v4-flash
          type: string
          description: |-
            * `openai` - OpenAI
            * `gemini` - Gemini
            * `dspy-gepa-gemini-flash` - Dspy Gepa Gemini Flash
            * `deepseek-v4-flash` - DeepSeek V4 Flash
          x-spec-enum-id: 6d1d2e77c71d1721
          writeOnly: true
        vocera_defined_metric_code:
          type: string
          readOnly: true
          description: |

            Vocera defined metric code for the metric.
            Example: `"7fd534f5"`
        priority_assignment_prompt:
          type: string
          description: |

            Priority assignment prompt for the metric.
        configuration:
          description: >

            Custom configuration parameters for specific metrics if metric
            supports it.

            Example:

            - For Infrastructure issues

            ```json

            {
                "infra_issues_timeout": 10
            }

            ```
        scenarios:
          writeOnly: true
        overall_score:
          type: string
          readOnly: true
        total_score:
          type: string
          readOnly: true
        kb_file_ids:
          description: |

            List of knowledge base file IDs for the metric.
            Example: `[123, 456]`
        knowledge_base_files:
          type: string
          readOnly: true
        metric_description_program: {}
        metric_description_variables:
          type: array
          items: {}
        evaluation_trigger_program: {}
        evaluation_trigger_variables:
          type: array
          items: {}
        alert_enabled:
          type: boolean
          description: |-

            Enable alerts for this metric when it fails (value=false).
            Only applicable to binary metrics (eval_type=binary).
            For other metric types, use significant_change_alert_status instead.
            Example: `true` or `false`
                    
        alert_type:
          enum:
            - disabled
            - normal
            - significant_change
          type: string
          description: |-
            * `disabled` - Alerts Disabled
            * `normal` - Normal Alerts
            * `significant_change` - Significant Change Alerts
          x-spec-enum-id: 9e2661f1aeca64cf
          default: disabled
        window_size:
          type: integer
          default: 50
        std_multiplier:
          type: number
          format: double
          default: 2
        ewma_alpha:
          type: number
          format: double
          default: 0.1
        significant_change_alert_status:
          enum:
            - enabled
            - disabled
          type: string
          x-spec-enum-id: 6d6f4d361b4ea1fb
          description: |-

            Alert status: enabled or disabled.


            * `enabled` - Enabled
            * `disabled` - Disabled
        significant_change_alert_direction:
          enum:
            - ''
            - increase
            - decrease
          type: string
          x-spec-enum-id: 1e86e60ca5cfba12
          description: >-
            Alert direction: increase only, decrease only, or both (empty =
            both).

            Example: `"increase"`, `"decrease"`, or `"both"`


            * `` - Both (Increase and Decrease)

            * `increase` - Increase Only

            * `decrease` - Decrease Only
        add_to_new_agents:
          type:
            - boolean
            - 'null'
          description: >-
            When enabled, this metric is automatically assigned to new agents
            created in the project.
        alert_filters:
          oneOf:
            - {}
            - type: 'null'
          description: Filters to apply before computing alerts (CallLogQueryFilter format)
        slack_workspace:
          type:
            - integer
            - 'null'
          description: Slack workspace to send alerts to
        slack_channel_id:
          type:
            - string
            - 'null'
          description: Override channel ID for this metric's alerts
          maxLength: 255
        apply_to_all_agents:
          type: boolean
          writeOnly: true
          default: false
          description: >-
            For observability_dropoff: when true, copies the dropoff_nodes from
            configuration to every other agent in the project.
        add_to_rubric:
          type: boolean
          writeOnly: true
          default: false
          description: >-
            If true, this metric is added to the project's call-success rubric
            on save (a sensible default rule is chosen by `eval_type`). If false
            on an existing rubric metric, it's removed from the rubric.
      required:
        - name
    MetricDetailSerializerV2:
      type: object
      properties:
        id:
          type: integer
          readOnly: true
        slug:
          type:
            - string
            - 'null'
          description: >-
            URL-friendly unique identifier in snake_case format. Example:
            "customer_satisfaction_1562"
          maxLength: 255
        project:
          type:
            - integer
            - 'null'
        agents:
          type: array
          items:
            type:
              - integer
              - 'null'
        name:
          type: string
          description: |-

            Name of the metric.
            Example: `"Customer Satisfaction"` or `"Appointment Booking"`
                    
          maxLength: 255
        description:
          type: string
          description: >-

            Description of what the metric measures.

            Example: `"Measures how satisfied customers are with the service
            provided"`
                    
        type:
          enum:
            - basic
            - custom_prompt
            - custom_code
            - llm_judge
          type: string
          x-spec-enum-id: b44700c0a6443b40
          description: >-

            Type of metric



            * `basic` - Basic (Deprecated in favor of LLM Judge)

            * `custom_prompt` - Custom Prompt ( Deprecated in favor of LLM
            Judge)

            * `custom_code` - Custom Code

            * `llm_judge` - LLM Judge
        eval_type:
          enum:
            - binary
            - continuous_qualitative
            - numeric
            - enum
          type: string
          description: |-
            * `binary` - Binary
            * `continuous_qualitative` - Continuous Qualitative
            * `numeric` - Numeric
            * `enum` - Enum
          x-spec-enum-id: b40eac6824409cc2
        enum_values:
          description: |

            List of possible enum values for enum type metrics.
            Example: `["satisfied", "unsatisfied"]`
        audio_enabled:
          type: boolean
          description: |-

            Whether this metric requires audio analysis.
            Example: `true` or `false`
                    
        prompt:
          type: string
          description: |

            Evaluation prompt for the metric.
            Example: `"Evaluate customer satisfaction based on conversation"`
        evaluation_trigger:
          enum:
            - always
            - automatic
            - custom
          type: string
          description: |-
            * `always` - Always
            * `automatic` - Automatic
            * `custom` - Custom
          x-spec-enum-id: ecd3c02e0e393ef5
        trigger_type:
          enum:
            - llm_judge
            - custom_code
          type: string
          x-spec-enum-id: 2adad4b8df61914f
          description: |-

            Type of trigger evaluation: LLM judge or custom code.
            Only used when evaluation_trigger is CUSTOM.
            Example: `"llm_judge"` or `"custom_code"`


            * `llm_judge` - LLM Judge
            * `custom_code` - Custom Code
        evaluation_trigger_prompt:
          type: string
          description: >

            Evaluation trigger prompt for the metric.

            Example: `"Evaluate metric only if call ended reason is
            main-agent-ended-call"`
        evaluation_trigger_custom_code:
          type: string
          description: >

            Python custom code to determine metric relevance. Code should set
            _result (bool) and _explanation (str).

            Example:

            ```python

            _result = True

            _explanation = "Metric is relevant"

            if "call_end_reason" in data and data["call_end_reason"] ==
            "customer-hung-up":
                _result = False
                _explanation = "Customer hung up, metric not applicable"
            ```
        priority_assignment_prompt:
          type: string
          description: |

            Priority assignment prompt for the metric.
        configuration:
          description: >

            Custom configuration parameters for specific metrics if metric
            supports it.

            Example:

            - For Infrastructure issues

            ```json

            {
                "infra_issues_timeout": 10
            }

            ```
        overall_score:
          type: string
          readOnly: true
          description: The overall score for this metric across all test sets
        total_score:
          type: string
          readOnly: true
          description: The total score for this metric
        knowledge_base_files:
          type: string
          readOnly: true
          description: Knowledge base files associated with this metric
        observability_enabled:
          type: boolean
          description: |-

            Enable this metric for observability.
            Example: `true` or `false`
                    
        simulation_enabled:
          type: boolean
          description: |-

            Enable this metric for simulations.
            Example: `true` or `false`
                    
        sampling_enabled:
          type: boolean
          description: Enable sampling for this metric using project-level sample rate
        alert_enabled:
          type: boolean
          description: |-

            Enable alerts for this metric when it fails (value=false).
            Only applicable to binary metrics (eval_type=binary).
            For other metric types, use significant_change_alert_status instead.
            Example: `true` or `false`
                    
        alert_type:
          enum:
            - disabled
            - normal
            - significant_change
          type: string
          description: |-
            * `disabled` - Alerts Disabled
            * `normal` - Normal Alerts
            * `significant_change` - Significant Change Alerts
          x-spec-enum-id: 9e2661f1aeca64cf
          default: disabled
        alert_filters:
          oneOf:
            - {}
            - type: 'null'
          description: Filters to apply before computing alerts (CallLogQueryFilter format)
        slack_workspace:
          type:
            - integer
            - 'null'
          description: Slack workspace to send alerts to
        slack_channel_id:
          type:
            - string
            - 'null'
          description: Override channel ID for this metric's alerts
          maxLength: 255
        significant_change_alert_status:
          enum:
            - enabled
            - disabled
          type: string
          x-spec-enum-id: 6d6f4d361b4ea1fb
          description: |-

            Alert status: enabled or disabled.


            * `enabled` - Enabled
            * `disabled` - Disabled
        significant_change_alert_direction:
          enum:
            - ''
            - increase
            - decrease
          type: string
          x-spec-enum-id: 1e86e60ca5cfba12
          description: >-
            Alert direction: increase only, decrease only, or both (empty =
            both).

            Example: `"increase"`, `"decrease"`, or `"both"`


            * `` - Both (Increase and Decrease)

            * `increase` - Increase Only

            * `decrease` - Decrease Only
        function_name:
          type:
            - string
            - 'null'
          description: |

            Predefined function name
            Example: `"get_latency"` or `"check_critical_deviations"`
          maxLength: 255
        custom_code:
          type: string
          description: >

            Python custom code for the metric.

            Example:

            ```python

            _resul = True

            _explanation = None

            if  "call_end_reason" in data and data["call_end_reason"] ==
            "customer_satisfaction":
                _result = True
                _explanation = "Customer expressed satisfaction with service"
            ```
        vocera_defined_metric_code:
          type: string
          description: |

            Vocera defined metric code for the metric.
            Example: `"7fd534f5"`
          maxLength: 255
        scenarios:
          writeOnly: true
        reviews:
          type: array
          items:
            $ref: '#/components/schemas/MetricReviewDetail'
          readOnly: true
          description: Reviews associated with the metric
        window_size:
          type: integer
          readOnly: true
          description: |

            Window size for rolling statistics calculation.
            Example: `50`
        std_multiplier:
          type: number
          format: double
          readOnly: true
          description: |

            Standard deviation multiplier for threshold calculation.
            Example: `2.0`
        ewma_alpha:
          type: number
          format: double
          readOnly: true
          description: >

            Alpha value for exponentially weighted moving average (EWMA)
            calculation.

            Example: `0.1`
        add_to_new_agents:
          type:
            - boolean
            - 'null'
          description: >-
            When enabled, this metric is automatically assigned to new agents
            created in the project.
        pending_optimisation_proposal:
          oneOf:
            - {}
            - type: 'null'
          readOnly: true
          description: >-
            Unsaved proposal from a metric-optimiser cron run. Shape:
            {description, evaluation_trigger, type, custom_code, score,
            baseline_score, cron_job_id, cron_job_name, proposed_at}.
      required:
        - eval_type
        - name
    MetricReviewDetail:
      type: object
      properties:
        id:
          type: integer
          readOnly: true
        test_set:
          allOf:
            - $ref: '#/components/schemas/TestSetInline'
          readOnly: true
        metric:
          type: integer
        expected_value:
          oneOf:
            - {}
            - type: 'null'
          description: |

            Metric expected value
            Example:
            - `5` or `0`
            - `one`, `two` or `three` [ enum type ]
        actual_value:
          oneOf:
            - {}
            - type: 'null'
          description: |

            Metric actual value
            Example:
            - `5` or `0`
            - `one`, `two` or `three` [ enum type ]
        explanation:
          description: >

            Metric explanation

            Example:

            ```json

            ["Agent failed to follow the opening script", "Missed key product
            information"]

            ```
        feedback:
          type: string
          description: |

            Metric feedback
            Example:
            - `"Great Call"`
        created_at:
          type: string
          format: date-time
          readOnly: true
          description: |

            Timestamp when the metric review was created
            Example: `"2021-01-01T00:00:00Z"`
        updated_at:
          type: string
          format: date-time
          readOnly: true
          description: |

            Timestamp when the metric review was last updated
            Example: `"2021-01-01T00:00:00Z"`
      required:
        - metric
    TestSetInline:
      type: object
      properties:
        id:
          type: integer
          readOnly: true
        agent:
          type: integer
        name:
          type: string
          description: |

            Name of the test set
            Example: `"Test Set 1"`
          maxLength: 255
        transcript:
          type: string
          description: >
            Full text transcript of the call.

            Example: 

            ```text

            [00:01] Testing Agent: Hello. 

            [00:02] Main Agent: Hello, how can I help you today?

            [00:03] Testing Agent: Well, I mean, sure. What time exactly are we
            talking about here

            [00:04] Main Agent: 6 PM.

            [00:05] Testing Agent: Great. I'll book that for you. Just a sec.

            [00:06] Main Agent: Okay.

            ```
        voice_recording_url:
          type: string
          readOnly: true
        call_end_reason:
          type: string
          description: |
            Reason why the call ended.
            Example: 
            - `"customer-ended-call"`
            - `"agent-ended-call"`
          maxLength: 255
        duration:
          type: string
          readOnly: true
        source_model:
          enum:
            - CallLog
            - Run
          type: string
          description: |-
            * `CallLog` - Call Log
            * `Run` - Run
          x-spec-enum-id: 1d8f6db20c0b4cac
          readOnly: true
        source_id:
          type: string
          readOnly: true
        created_at:
          type: string
          format: date-time
          readOnly: true
          description: |-
            When this record was created.
            Example: `2024-03-15T10:30:45Z`
        updated_at:
          type: string
          format: date-time
          readOnly: true
          description: |-
            When this record was last updated.
            Example: `2024-03-15T10:35:11Z`
      required:
        - agent
  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.

````