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

# Collectors

> Run a set of metrics automatically on every conversation that matches

<Info>
  **Prefer to keep this in your repo?** Collectors can be defined as [config as code](/documentation/config-as-code/collectors) (YAML in git, applied with the [CLI](/documentation/sdks/cli)) instead of built in the dashboard.
</Info>

## Overview

A collector runs a set of metrics on the calls (or chats) it matches. Instead of triggering metric collection by hand, you define the segment of conversations you care about (by agent, source, or property) and Roark scores every matching conversation as it comes in.

Collectors live under **Measure → Metrics**: the Metrics page shows a Collectors strip at the top, and **Manage collectors** opens the full list at `/metrics/collectors`.

A collector is made of four things:

1. **Name**: how it appears in the collectors list
2. **Modality**: Call or Chat. A collector fires for exactly one modality, and this is locked after creation
3. **Conditions** (optional): the segment of conversations it matches. Leave empty to match all calls (or all chats)
4. **Metrics**: the metrics to run on every match, each with optional pass/fail thresholds

***

## Creating a Collector

<Steps>
  <Step title="Start a new collector">
    On `/metrics/collectors`, click **New collector**. The editor reads as a sentence: "When a **call** matches…" Click the chip to switch between Call and Chat. Once the collector is created, the modality is locked.
  </Step>

  <Step title="Define the segment">
    Add conditions to target specific conversations, or leave the conditions empty to match everything. Use **Add condition** and **Add OR condition** to build a group, and **Add AND condition group** to require a second group to match as well.
  </Step>

  <Step title="Pick the metrics">
    Under **Evaluate these metrics**, add the metrics to run. Each picked metric runs on every conversation that matches the scope above. Where a metric has multiple variants, choose which variant's prompt and config apply.
  </Step>

  <Step title="Add thresholds (optional)">
    On any picked metric, click **Add pass/fail threshold** to turn its raw value into a pass/fail outcome, for example, "Pass if ≥ 7".
  </Step>

  <Step title="Create and name it">
    Click **Create collector**. Roark suggests a name built from the metrics and conditions. Keep it or edit it, then confirm. Incoming conversations that match your conditions are evaluated from then on.
  </Step>
</Steps>

***

## Conditions

Conditions scope a collector to a segment of conversations. **Groups combine with AND; conditions within a group combine with OR.** An empty condition set matches every call (or chat) in the project.

| Type         | Matches                                   | Inputs                                                       |
| :----------- | :---------------------------------------- | :----------------------------------------------------------- |
| **Agent**    | Conversations handled by specific agents  | Agent picker                                                 |
| **Source**   | Conversations from a specific integration | LiveKit Cloud, Vapi, Retell, ElevenLabs, Leaping, API, Bland |
| **Property** | Conversations by custom metadata          | Property key + operator + value                              |

Property conditions support these operators:

| Operator                       | Comparison                            |
| :----------------------------- | :------------------------------------ |
| equals / does not equal        | Exact match                           |
| contains                       | Substring match                       |
| starts with                    | Prefix match                          |
| is greater than / is less than | Numeric comparison                    |
| is at least / is at most       | Numeric comparison, inclusive (≥ / ≤) |

<Tip>
  A group like "Agent is Billing Bot OR Agent is Sales Bot" AND "Source is Vapi" runs the collector's metrics only on Vapi calls handled by either agent.
</Tip>

***

## Pass/Fail Thresholds

Thresholds turn a metric's raw value into a pass/fail check, configured inline on each picked metric:

* **Add pass/fail threshold** adds a row that reads "Pass if `[operator]` `[value]`" (for example, Pass if ≥ 0.7).
* Thresholds that already exist for the metric appear as read-only rows with an **Include if** checkbox, so you can opt an existing threshold into this collector instead of creating a duplicate. If a new row matches an existing threshold, Roark warns you and dedupes it. It won't be created again.

Each saved threshold is a derived metric in its own right (named like "Empathy ≥ 7", scored Pass/Fail), added to the collector alongside the source metric. Thresholds are available for Scale, Numeric, Count, Boolean, and Classification outputs.

<Card title="Thresholds Guide" icon="sliders-horizontal" href="/documentation/metrics/thresholds">
  Learn about operators and how derived threshold metrics work
</Card>

***

## Active and Paused

Every custom collector has a status toggle in the list: **Active** collectors evaluate matching conversations; **Paused** collectors don't. Pause a collector instead of deleting it if you might need it again. Deleting a collector stops it from collecting its metrics, but the metric definitions themselves are unaffected.

***

## System Collectors

Roark ships system collectors, the baseline coverage that keeps core metrics running on all your calls and chats. They're marked with a **System** shield badge and sort first in the list.

|                          | System collectors | Custom collectors         |
| :----------------------- | :---------------- | :------------------------ |
| **Created by**           | Roark             | You, via dashboard or API |
| **Editable / deletable** | No                | Yes                       |
| **Status**               | Always run        | Active or Paused          |

***

## Per-Agent Collectors

Each agent's detail page has a **Collectors** section listing the collectors that target that agent. These are the same collectors (just scoped by an Agent condition) so a collector created from the agent page shows up in the main `/metrics/collectors` list too, and vice versa.

***

## API and SDK Access

Collectors are fully manageable programmatically via the [Node.js SDK](/documentation/sdks/node-sdk) and REST API.

<Note>
  The API keeps the older **metric policy** naming: the SDK client is `client.metricPolicy.*` and the REST endpoints are `/v1/metric/policies`. A "policy" in the API is exactly a collector in the dashboard.
</Note>

### Create

```typescript theme={"theme":{"light":"everforest-light","dark":"everforest-dark"}}
const collector = await client.metricPolicy.create({
  name: 'Production Agent Quality Checks',
  modality: 'call', // 'call' or 'chat', locked after creation
  status: 'ACTIVE',
  conditions: [
    {
      conditions: [
        {
          conditionType: 'AGENT',
          conditionKey: 'your-agent-id',
        },
      ],
    },
  ],
  metrics: [
    { id: 'metric-definition-uuid-1' },
    { id: 'metric-definition-uuid-2' },
  ],
})
```

| Field        | Type   | Required | Description                                                                                                   |
| :----------- | :----- | :------- | :------------------------------------------------------------------------------------------------------------ |
| `name`       | string | Yes      | Descriptive name for the collector                                                                            |
| `modality`   | string | Yes      | `call` or `chat`; the collector only fires for this modality and can only reference metrics that support it   |
| `status`     | string | No       | `ACTIVE` (default) or `INACTIVE` (Paused)                                                                     |
| `conditions` | array  | No       | Condition groups: groups AND together, conditions within a group OR together; omit to match all conversations |
| `metrics`    | array  | Yes      | Metric definitions to run (minimum 1)                                                                         |

### Condition fields

| `conditionType` | `conditionKey`                      | `conditionOperator`                                                                                                             | `conditionValue`         |
| :-------------- | :---------------------------------- | :------------------------------------------------------------------------------------------------------------------------------ | :----------------------- |
| `AGENT`         | Agent ID                            | N/A                                                                                                                             | N/A                      |
| `CALL_SOURCE`   | Source name (e.g. `VAPI`, `RETELL`) | N/A                                                                                                                             | N/A                      |
| `CALL_PROPERTY` | Property key                        | `EQUALS`, `NOT_EQUALS`, `CONTAINS`, `STARTS_WITH`, `GREATER_THAN`, `LESS_THAN`, `GREATER_THAN_OR_EQUALS`, `LESS_THAN_OR_EQUALS` | Value to compare against |

`GREATER_THAN_OR_EQUALS` and `LESS_THAN_OR_EQUALS` correspond to the dashboard's "is at least" and "is at most" operators.

**Example: collector for Vapi calls only**

```typescript theme={"theme":{"light":"everforest-light","dark":"everforest-dark"}}
const collector = await client.metricPolicy.create({
  name: 'Vapi Call Metrics',
  modality: 'call',
  conditions: [
    {
      conditions: [
        {
          conditionType: 'CALL_SOURCE',
          conditionKey: 'VAPI',
        },
      ],
    },
  ],
  metrics: [{ id: 'metric-definition-uuid' }],
})
```

### List, get, update, delete

```typescript theme={"theme":{"light":"everforest-light","dark":"everforest-dark"}}
// List (limit 1-50, default 20; cursor pagination via `after`)
const collectors = await client.metricPolicy.list({ status: 'ACTIVE', limit: 50 })

// Get one
const collector = await client.metricPolicy.getByID('policy-id')

// Update: all fields optional; pass an empty `conditions` array to match everything
const updated = await client.metricPolicy.update('policy-id', {
  name: 'Updated Collector Name',
  status: 'INACTIVE',
})

// Delete
const result = await client.metricPolicy.delete('policy-id')
```

<Warning>
  System collectors (`type: "SYSTEM"` in API responses) cannot be modified or deleted.
</Warning>

***

## Best Practices

<AccordionGroup>
  <Accordion title="Start Broad, Then Narrow">
    Create a collector with no conditions to run key metrics on all calls, then add targeted collectors with conditions for specific segments.
  </Accordion>

  <Accordion title="Use Conditions for Targeted Collection">
    If you only need certain metrics for specific agents or sources, scope the collector so you're not scoring conversations you don't care about.
  </Accordion>

  <Accordion title="Keep Collectors Organized">
    Use names that say what the collector targets and measures. The auto-suggested name (metric names plus a condition summary) is a good starting point.
  </Accordion>

  <Accordion title="Pause Instead of Delete">
    Pause a collector if you might need it again later. Deleting stops collection but leaves the metric definitions intact.
  </Accordion>
</AccordionGroup>

***

## What's Next

<CardGroup cols={2}>
  <Card title="Custom Metrics" icon="gauge" href="/documentation/metrics/custom-metrics">
    Learn about metric types, scopes, and how to create custom metrics
  </Card>

  <Card title="Studio" icon="pencil-ruler" href="/documentation/metrics/studio">
    Author and test metrics, then bind them to a collector from the editor
  </Card>

  <Card title="Thresholds" icon="sliders-horizontal" href="/documentation/metrics/thresholds">
    Turn raw metric values into pass/fail outcomes
  </Card>

  <Card title="Metric Collection Jobs" icon="play" href="/documentation/metrics/metric-collection-jobs">
    Run metrics on demand for specific calls
  </Card>
</CardGroup>
