---
title: "Create custom metric definition"
method: POST
path: "/v1/metric/definitions"
tags: ["Metric"]
---

# Create custom metric definition

`POST /v1/metric/definitions`

Create a new metric definition. The `calculationType` field selects the variant: LLM_JUDGE (LLM-evaluated), FORMULA (computed from a math expression over other metrics), or PATTERN (detects a trigger→outcome pattern within a window). To create a threshold on top of an existing metric, use `POST /metric/definitions/{idOrSlug}/thresholds` instead.

## Request body

- union — Input for creating a new metric definition. `calculationType` selects the variant and defaults to LLM_JUDGE when omitted (legacy prompt-metric payloads remain valid). To create a threshold, use the threshold sub-resource.
  - PromptMetricInput
    - `calculationType` 'LLM_JUDGE', required — LLM-evaluated metric.
    - `name` string, required — Name of the metric
    - `slug` string — Stable slug for the metric. Auto-generated from name if omitted.
    - `metricId` string — Alias of `slug` accepted for backwards compatibility. Use `slug` for new integrations.
    - `outputType` 'COUNT' | 'NUMERIC' | 'BOOLEAN' | 'SCALE' | 'TEXT' | 'CLASSIFICATION' | 'OFFSET', required — Type of value this metric produces
    - `scope` 'GLOBAL' | 'PER_PARTICIPANT' — Whether metric is global or per-participant (default: GLOBAL)
    - `participantRole` 'AGENT' | 'CUSTOMER' | 'SIMULATED_CUSTOMER' | 'BACKGROUND_SPEAKER' — Participant role to evaluate. Required when scope is PER_PARTICIPANT.
    - `supportedContexts` string[] — Which levels this metric can produce values at (default: ["CALL"])
    - `llmPrompt` string — LLM prompt/criteria for evaluating this metric. Required for BOOLEAN, NUMERIC, TEXT, and SCALE types.
    - `analysisPackageId` string, uuid — ID of the analysis package to add this metric to. Optional: when omitted, the metric is added to a default "Custom Metrics" package for your project (created automatically the first time).
    - `booleanTrueLabel` string — Label for the true case (only for BOOLEAN type)
    - `booleanFalseLabel` string — Label for the false case (only for BOOLEAN type)
    - `scaleMin` integer — Minimum value for scale. Required for SCALE type.
    - `scaleMax` integer — Maximum value for scale. Required for SCALE type.
    - `scaleLabels` object[] — Labels for scale ranges (only for SCALE type)
      - `rangeMin` number, required — Minimum value for this label range
      - `rangeMax` number, required — Maximum value for this label range
      - `label` string, required — Label for this range
      - `description` string — Description of what this range means
      - `displayOrder` integer, required — Display order of this label
      - `colorHex` string — Hex color code for this label (e.g. "#FF0000")
    - `classificationOptions` object[] — Options for classification. Required for CLASSIFICATION type.
      - `label` string, required
      - `description` string, required
      - `displayOrder` integer, required
    - `maxClassifications` integer — Maximum number of classifications that can be selected (only for CLASSIFICATION type)
  - FormulaMetricInput
    - `calculationType` 'FORMULA', required — Metric computed by evaluating a mathematical expression over other metrics.
    - `name` string, required — Name of the metric
    - `slug` string — Stable slug for the metric. Auto-generated from name if omitted.
    - `metricId` string — Alias of `slug` accepted for backwards compatibility. Use `slug` for new integrations.
    - `outputType` 'NUMERIC' | 'BOOLEAN', required — Output type of the formula. NUMERIC for arithmetic expressions, BOOLEAN for comparison expressions.
    - `formula` string, required — Formula expression using `{{id:<uuid>}}` references to source metrics. Operators depend on output type: +, -, *, / for NUMERIC; ==, !=, >=, <=, >, < for BOOLEAN.
    - `sources` object[], required — Source metrics referenced by the formula. Minimum 2.
      - `sourceMetricDefinitionId` string, uuid, required — ID of a metric referenced in the formula
      - `sourceVariantId` string, uuid — Variant of the source metric to use
    - `analysisPackageId` string, uuid — ID of the analysis package to add this metric to. Optional: when omitted, the metric is added to a default "Custom Metrics" package for your project (created automatically the first time).
  - PatternMetricInput
    - `calculationType` 'PATTERN', required — Metric detecting temporal patterns: a trigger condition followed by an outcome within a window.
    - `name` string, required — Name of the metric
    - `slug` string — Stable slug for the metric. Auto-generated from name if omitted.
    - `metricId` string — Alias of `slug` accepted for backwards compatibility. Use `slug` for new integrations.
    - `operation` 'PATTERN_EXISTS' | 'PATTERN_COUNT' | 'OUTCOME_AGGREGATE', required — Pattern operation. PATTERN_EXISTS produces a BOOLEAN; PATTERN_COUNT produces a NUMERIC count; OUTCOME_AGGREGATE aggregates a numeric outcome.
    - `windowMode` 'seconds' | 'segments' — Unit for trigger/outcome window values (default: seconds)
    - `trigger` object — Single trigger condition. Use either trigger or triggers + triggerCombinator.
      - `sourceMetricDefinitionId` string, uuid, required
      - `operator` 'GREATER_THAN' | 'GREATER_THAN_OR_EQUALS' | 'LESS_THAN' | 'LESS_THAN_OR_EQUALS' | 'EQUALS' | 'NOT_EQUALS', required
      - `thresholdValue` string, required
      - `sourceParticipantRole` 'AGENT' | 'CUSTOMER' | 'SIMULATED_CUSTOMER' | 'BACKGROUND_SPEAKER'
      - `sourceVariantId` string, uuid
    - `triggers` object[] — Multiple trigger conditions. Use with triggerCombinator.
      - `sourceMetricDefinitionId` string, uuid, required
      - `operator` 'GREATER_THAN' | 'GREATER_THAN_OR_EQUALS' | 'LESS_THAN' | 'LESS_THAN_OR_EQUALS' | 'EQUALS' | 'NOT_EQUALS', required
      - `thresholdValue` string, required
      - `sourceParticipantRole` 'AGENT' | 'CUSTOMER' | 'SIMULATED_CUSTOMER' | 'BACKGROUND_SPEAKER'
      - `sourceVariantId` string, uuid
    - `triggerCombinator` 'AND' | 'OR' — How to combine multiple triggers. Required when triggers has more than 1 entry.
    - `outcome` object, required — Outcome condition evaluated within the window relative to the trigger.
      - `sourceMetricDefinitionId` string, uuid, required
      - `operator` 'GREATER_THAN' | 'GREATER_THAN_OR_EQUALS' | 'LESS_THAN' | 'LESS_THAN_OR_EQUALS' | 'EQUALS' | 'NOT_EQUALS', required
      - `thresholdValue` string, required
      - `sourceParticipantRole` 'AGENT' | 'CUSTOMER' | 'SIMULATED_CUSTOMER' | 'BACKGROUND_SPEAKER'
      - `sourceVariantId` string, uuid
      - `windowAfter` integer, required — How far after the trigger to look for the outcome (in seconds or segments, see windowMode)
      - `windowBefore` integer — How far before the trigger to look for the outcome (default: 0)
    - `analysisPackageId` string, uuid — ID of the analysis package to add this metric to. Optional: when omitted, the metric is added to a default "Custom Metrics" package for your project (created automatically the first time).

## Response `201`

The created metric definition

- object
  - `data` union, required — The created metric definition. The variant is selected by `calculationType`.
    - LlmJudgeMetricResponse
      - `id` string, uuid, required — Unique identifier for the metric definition
      - `slug` string, required — Stable metric slug (e.g. "call_reason", "customer_satisfaction")
      - `metricId` string, required — Alias of `slug` retained for backwards compatibility. Same value as `slug`.
      - `variantId` string, uuid, required — The resolved variant this response reflects (org-scoped Default if the org has customized it, otherwise the system Default). Pass this as sourceVariantId when building a derived metric off this one to pin the exact config.
      - `versionId` string, uuid, required — The variant's current version. Immutable snapshot of the config — editing the metric produces a new versionId. Use it to detect config changes.
      - `name` string, required — Name of the metric
      - `description` string, required — Description of what the metric measures
      - `type` 'COUNT' | 'NUMERIC' | 'BOOLEAN' | 'SCALE' | 'TEXT' | 'CLASSIFICATION' | 'OFFSET', required — Type of value this metric produces
      - `scope` 'GLOBAL' | 'PER_PARTICIPANT', required — Whether metric is global or per-participant
      - `supportedContexts` string[], required — Which levels this metric can produce values at
      - `unit` object — Unit information if applicable
        - `name` string, required — Name of the unit
        - `symbol` string, nullable, required — Symbol for the unit
      - `calculationType` 'LLM_JUDGE', required — Metric evaluated by an LLM against a prompt.
    - FormulaMetricResponse
      - `id` string, uuid, required — Unique identifier for the metric definition
      - `slug` string, required — Stable metric slug (e.g. "call_reason", "customer_satisfaction")
      - `metricId` string, required — Alias of `slug` retained for backwards compatibility. Same value as `slug`.
      - `variantId` string, uuid, required — The resolved variant this response reflects (org-scoped Default if the org has customized it, otherwise the system Default). Pass this as sourceVariantId when building a derived metric off this one to pin the exact config.
      - `versionId` string, uuid, required — The variant's current version. Immutable snapshot of the config — editing the metric produces a new versionId. Use it to detect config changes.
      - `name` string, required — Name of the metric
      - `description` string, required — Description of what the metric measures
      - `type` 'COUNT' | 'NUMERIC' | 'BOOLEAN' | 'SCALE' | 'TEXT' | 'CLASSIFICATION' | 'OFFSET', required — Type of value this metric produces
      - `scope` 'GLOBAL' | 'PER_PARTICIPANT', required — Whether metric is global or per-participant
      - `supportedContexts` string[], required — Which levels this metric can produce values at
      - `unit` object — Unit information if applicable
        - `name` string, required — Name of the unit
        - `symbol` string, nullable, required — Symbol for the unit
      - `calculationType` 'FORMULA', required — Metric computed by evaluating an expression over other metrics.
      - `formula` FormulaMetricDetails, required
        - `expression` string, required
        - `sources` object[], required
          - `sourceMetricDefinitionId` string, uuid, required
          - `sourceVariantId` string, uuid, nullable, required
    - PatternMetricResponse
      - `id` string, uuid, required — Unique identifier for the metric definition
      - `slug` string, required — Stable metric slug (e.g. "call_reason", "customer_satisfaction")
      - `metricId` string, required — Alias of `slug` retained for backwards compatibility. Same value as `slug`.
      - `variantId` string, uuid, required — The resolved variant this response reflects (org-scoped Default if the org has customized it, otherwise the system Default). Pass this as sourceVariantId when building a derived metric off this one to pin the exact config.
      - `versionId` string, uuid, required — The variant's current version. Immutable snapshot of the config — editing the metric produces a new versionId. Use it to detect config changes.
      - `name` string, required — Name of the metric
      - `description` string, required — Description of what the metric measures
      - `type` 'COUNT' | 'NUMERIC' | 'BOOLEAN' | 'SCALE' | 'TEXT' | 'CLASSIFICATION' | 'OFFSET', required — Type of value this metric produces
      - `scope` 'GLOBAL' | 'PER_PARTICIPANT', required — Whether metric is global or per-participant
      - `supportedContexts` string[], required — Which levels this metric can produce values at
      - `unit` object — Unit information if applicable
        - `name` string, required — Name of the unit
        - `symbol` string, nullable, required — Symbol for the unit
      - `calculationType` 'PATTERN', required — Metric detecting a trigger condition followed by an outcome within a window.
      - `pattern` PatternMetricDetails, required
        - `operation` 'PATTERN_EXISTS' | 'PATTERN_COUNT' | 'OUTCOME_AGGREGATE', required
        - `windowMode` string, nullable, required
        - `triggerCombinator` 'AND' | 'OR', nullable, required
        - `triggers` object[], required
          - `sourceMetricDefinitionId` string, uuid, required
          - `operator` 'GREATER_THAN' | 'GREATER_THAN_OR_EQUALS' | 'LESS_THAN' | 'LESS_THAN_OR_EQUALS' | 'EQUALS' | 'NOT_EQUALS', required
          - `thresholdValue` string, required
          - `sourceParticipantRole` 'AGENT' | 'CUSTOMER' | 'SIMULATED_CUSTOMER' | 'BACKGROUND_SPEAKER', nullable, required
          - `sourceVariantId` string, uuid, nullable, required
        - `outcome` object, nullable, required
          - `sourceMetricDefinitionId` string, uuid, required
          - `operator` 'GREATER_THAN' | 'GREATER_THAN_OR_EQUALS' | 'LESS_THAN' | 'LESS_THAN_OR_EQUALS' | 'EQUALS' | 'NOT_EQUALS', required
          - `thresholdValue` string, required
          - `sourceParticipantRole` 'AGENT' | 'CUSTOMER' | 'SIMULATED_CUSTOMER' | 'BACKGROUND_SPEAKER', nullable, required
          - `sourceVariantId` string, uuid, nullable, required
          - `windowBefore` integer, nullable, required
          - `windowAfter` integer, nullable, required

## Other responses

- `400` — Bad Request
- `401` — Unauthorized
- `403` — Forbidden
- `429` — Too Many Requests
- `500` — Internal Server Error

## Changes

- **2026-08-28** `1d61b68e9429` — 3 info
  - the request property `oneOf[subschema #1: LLM judge metric]/analysisPackageId` became optional
  - the request property `oneOf[subschema #2: Formula metric]/analysisPackageId` became optional
  - the request property `oneOf[subschema #3: Pattern metric]/analysisPackageId` became optional
- **2026-08-17** `887b091b3d81` — 10 breaking, 26 warning, 3 info
  - the request's body type/format changed from `object`/`` to ``/``
  - added `#/components/schemas/LlmJudgeMetricResponse, #/components/schemas/FormulaMetricResponse, #/components/schemas/PatternMetricResponse` to the `data` response property `oneOf` list for the response status `201`
  - the `data` response's property type/format changed from `object`/`` to ``/`` for status `201`
  - removed the required property `data/description` from the response with the `201` status
  - …35 more

[Change history](https://skmtc.dev/roarkhq/apis/roark-analytics-api/changes/v1/metric/definitions/post.md)

---

[API](https://skmtc.dev/roarkhq/apis/roark-analytics-api.md) · [All operations](https://skmtc.dev/roarkhq/apis/roark-analytics-api/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/roarkhq/roark-analytics-api/revisions/1d61b68e9429/schema)
