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

# Thresholds

> Define pass/fail criteria for your metrics

## Overview

Thresholds turn raw metric values into clear **pass/fail outcomes**. When you add a threshold to a metric, Roark mints a derived boolean metric that automatically evaluates whether each conversation meets your criteria.

For example, a threshold of `>= 7` on `Customer Satisfaction` produces a Pass whenever the score is 7 or above, and a Fail otherwise.

***

## How Thresholds Work

Each threshold is a **derived metric** in its own right:

1. The source metric is collected as usual (e.g., a satisfaction score of `8`)
2. The threshold compares the value against your condition (e.g., `>= 7`)
3. A boolean result is produced with the labels **Pass** and **Fail**
4. The derived metric is stored alongside the original, so both show up in reporting

The derived metric is named after its rule — `Customer Satisfaction >= 7` — and uses the `THRESHOLD` calculation type with a Boolean output. Because it's a real metric definition, the same threshold can be reused across collectors.

<Note>
  Thresholds are available on these metric output types: **Scale**, **Numeric**, **Count**, **Boolean**, and **Classification**.
</Note>

***

## Adding a Threshold

Thresholds can be configured from several places in Roark:

* **[Collectors](/documentation/metrics/metric-collectors)** — Each picked metric in the collector editor has a **Pass/Fail Threshold(s)** block with an **Add pass/fail threshold** button
* **[Studio](/documentation/metrics/studio)** — In Evaluate mode, configure thresholds inline per metric before running a battery of evals
* **[Simulation Run Plans](/documentation/simulation-testing/run-plans)** — Set pass/fail checks for simulation testing

The configuration is the same everywhere: each threshold row reads **"Pass if \[operator] \[value]"**.

### Reusing Saved Thresholds

Because thresholds are metric definitions, ones you've already created appear as read-only rows with an **Include if** checkbox — tick it to opt an existing threshold into the current collector. If you try to add a rule that matches a saved threshold, Roark warns "Matches an existing threshold — it won't be created again" and reuses the existing one instead of creating a duplicate.

***

## Operators

The available operators depend on the metric's output type.

### Numeric Types (Scale, Numeric, Count)

| Operator               | Symbol | Example                   |
| :--------------------- | :----- | :------------------------ |
| Greater than           | `>`    | Score `>` 5               |
| Greater than or equals | `>=`   | Score `>=` 7              |
| Less than              | `<`    | Response time `<` 3000ms  |
| Less than or equals    | `<=`   | Response time `<=` 2000ms |
| Equals                 | `=`    | Count `=` 0               |
| Not equals             | `!=`   | Count `!=` 0              |

### Categorical Types (Boolean, Classification)

| Operator   | Symbol | Example                       |
| :--------- | :----- | :---------------------------- |
| Equals     | `=`    | Compliance check `=` true     |
| Not equals | `!=`   | Call outcome `!=` "escalated" |

***

## API-Only Options

The UI keeps threshold rows simple — an operator and a value. The REST API supports two additional options when creating thresholds programmatically.

<Note>
  These options are set via the API's `CreateThresholdInput` and are not exposed in the Collectors or Studio UI.
</Note>

### Aggregation Modes

When a metric produces multiple values per call (e.g., a per-segment metric that fires on every turn), the `aggregationMode` field determines how those values are combined before the comparison is applied.

| Mode        | Description                                                                  | Example                                 |
| :---------- | :--------------------------------------------------------------------------- | :-------------------------------------- |
| **Each**    | Compare every value individually — fails if any single value fails (default) | Each response time `<` 5000ms           |
| **Average** | Average all values, then apply the threshold                                 | Average sentiment `>=` 6                |
| **Min**     | Use the minimum value                                                        | Min confidence `>=` 0.8                 |
| **Max**     | Use the maximum value                                                        | Max response time `<` 10000ms           |
| **Median**  | Use the median value                                                         | Median score `>=` 7                     |
| **Sum**     | Sum all values, then apply the threshold                                     | Total talk time `<=` 300000ms           |
| **P95**     | Use the 95th percentile value                                                | P95 response time `<` 5000ms            |
| **P99**     | Use the 99th percentile value                                                | P99 latency `<` 8000ms                  |
| **Count**   | Count how many values match, and fire when `countThreshold` is met           | No more than 2 segments below threshold |

### Participant Role Filtering

For metrics with `PER_PARTICIPANT` scope, the `sourceParticipantRole` field narrows the threshold to a specific speaker: `AGENT`, `CUSTOMER`, `SIMULATED_CUSTOMER`, or `BACKGROUND_SPEAKER`. This is useful when a metric like sentiment is tracked for both speakers but you only want to set a threshold on the agent's performance.

***

## Examples

<AccordionGroup>
  <Accordion title="Customer Satisfaction ≥ 7">
    **Source metric:** Customer Satisfaction (Scale 1-10)
    **Operator:** Greater than or equals
    **Value:** 7
    **Result:** Pass if satisfaction is 7 or above, Fail otherwise. The derived metric is named `Customer Satisfaction >= 7`.
  </Accordion>

  <Accordion title="Identity Verified Equals True">
    **Source metric:** Identity Verified (Boolean)
    **Operator:** Equals
    **Value:** true
    **Result:** Pass if the agent verified the caller's identity
  </Accordion>

  <Accordion title="Agent Response Time Under 1 Second (API)">
    **Source metric:** Response Time (Numeric, per-segment)
    **Operator:** Less than
    **Value:** 1000 (milliseconds)
    **Aggregation (API-only):** P95
    **Participant Role (API-only):** Agent
    **Result:** Pass if 95th percentile agent response time is under 1 second
  </Accordion>

  <Accordion title="No More Than 2 Failed Segments (API, Count Mode)">
    **Source metric:** Tone Appropriate (Boolean, per-segment)
    **Operator:** Equals
    **Value:** true
    **Aggregation (API-only):** Count (`countThreshold`: 2)
    **Result:** Pass if no more than 2 segments have an inappropriate tone
  </Accordion>
</AccordionGroup>

***

## What's Next

<CardGroup cols={2}>
  <Card title="Collectors" icon="shield-check" href="/documentation/metrics/metric-collectors">
    Add thresholds to the metrics a collector runs
  </Card>

  <Card title="Studio" icon="square-terminal" href="/documentation/metrics/studio">
    Test thresholds in Evaluate mode before deploying
  </Card>

  <Card title="Run Plans" icon="list-checks" href="/documentation/simulation-testing/run-plans">
    Set pass/fail criteria for simulation testing
  </Card>

  <Card title="Custom Metrics" icon="gauge" href="/documentation/metrics/custom-metrics">
    Learn about metric types, scopes, and output formats
  </Card>
</CardGroup>
