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

# Alerts

> Set up alerts in Toqan Router to get notified when LLM cost, latency, errors, or guardrail results cross a threshold, without watching a dashboard.

See [HTTP URLs and authentication](/docs/reference/base-urls.md) and the API reference for complete request and response formats.

## **What Are Alerts**

**Traces** record what happened. **Alerts** report when it happened, without anyone having to look.

An **Alert** watches one metric in one **Project**, on a chosen schedule, and sends a notification the moment that metric crosses a defined threshold. A second notification follows when the metric recovers.

The **Recent runs** column renders each alert's evaluation history as a bar strip, showing at a glance whether it has been evaluating cleanly or breaching.

## **What Alerts Can Watch**

Each **Alert** watches a single metric. Alerts generally fall into four categories:

> [card] Suspicious cost
>
> Catch spend spikes before the invoice does. A runaway retry loop, a prompt
> that grew, or a switch to a more expensive model surfaces within minutes.

> [card] Unusual latency
>
> Watch average or p95 latency. Provider degradation and slow tool calls
> appear here long before they register as errors.

> [card] Guardrail results
>
> Watch guardrail pass rate or average guardrail score. A drop means the
> model started producing output the checks reject, the earliest available
> signal that quality regressed.

> [card] Errors
>
> Watch failed request counts or error rate, scoped to a provider, model,
> or **Deployment**.

> [!NOTE]
>
> **Experiment** runs are excluded from alert calculations, so experiment data
> does not contribute to alert thresholds.

The **Metric** dropdown groups every metric under **Usage** or **Guardrails**:

| Metric group | Metrics |
| - | - |
| **Usage** | `LLM cost`, `Error rate`, `Errors`, `Latency (avg)`, `Latency p50`, `Latency p95`, `Latency p99`, `Requests`, `Tokens`, `Time to first token (avg)`, `Time to first token p50`, `Time to first token p95`, `Time to first token runs` |
| **Guardrails** | `Guardrail error rate`, `Guardrail errors`, `Guardrail failure rate`, `Guardrail pass rate`, `Guardrail runs`, `Guardrail score (avg)`, `Guardrail block rate`, `Guardrail runs (rules)`, `Guardrails triggered` |

## **Creating An Alert**

> [tab] AI Studio
>
> **1. Open Alerts**
>
> Open **Alerts** in the **Observability** section of the sidebar, then choose **+ Alert**.
>
> **2. Name the alert**
>
> Enter a **Name** that describes the problem rather than the metric. `High spend on production` reads better than `cost alert`. Names must be unique within the workspace.
>
> Add an optional **Description**, and confirm the **Project**. An **Alert** belongs to exactly one **Project**, and the **Project** cannot be changed after creation.
>
> **3. Choose a metric**
>
> Pick a **Metric** from the dropdown, grouped under **Usage** and **Guardrails**. The default is `LLM cost`, and the stored `signal` is derived from the metric.
>
> A **Guardrails** metric adds a guardrail picker below the dropdown. Leaving it empty covers every guardrail in the **Project**. Selecting specific **Guardrails** limits the alert to those.
>
> **4. Set the condition**
>
> The condition reads as a single sentence: trigger when the value is **\[comparator]** **\[threshold]** over the last **\[window]**, checked **\[frequency]**.
>
> See [Condition options](#condition-options) for the full set of values, and note that thresholds are entered in each metric's own unit.
>
> **5. Narrow the scope with filters**
>
> Without filters, the **Alert** evaluates the metric across the whole **Project**. Filters restrict it to a specific slice. This step is optional. See [Filters](#filters).
>
> **6. Choose where it notifies**
>
> Under **Notify via**, select one or more **Notifiers**, up to 10 per **Alert**. **Notifiers** are reusable destinations for email, Slack, or generic webhooks, managed under **Settings** > **Notifiers**. See [Notifiers](/docs/ai-studio/observability/notifiers.md) for the channels and their fields, or create one inline from the form.
>
> **Notifiers** are optional. An **Alert** without any still evaluates and records its triggers, but notifies nobody.
>
> **7. Check the preview, then save**
>
> The right-hand pane plots the metric over 1h, 4h, 1d, or 7d alongside the resolved query and stored config. **Results** breaks down as **Overview**, **Query**, and **Config**: **Overview** shows **Status**, **Next run**, and **Type**, and **Config** repeats **Threshold**, **Range**, **Frequency**, **Delay**, and **Notifiers**. **Delay** reads **30 seconds** in the preview. Use it to check the threshold against real traffic before committing. A threshold that has never been crossed is as unhelpful as one that fires constantly.
>
> Choose **Create Alert**. New **Alerts** are enabled immediately.

> [tab] API / SDK
>
> ```bash cURL theme={"theme":{"light":"github-light","dark":"github-dark"}}
> curl --location 'https://router.toqan.ai/eu/v2/alerts' \
> --header "Authorization: Bearer $TOQAN_API_KEY" \
> --header 'Content-Type: application/json' \
> --data-raw '{
>     "display_name": "High spend on production",
>     "description": "LLM cost above $30 in any 15 minute window",
>     "project_id": "01JQ8Z0MB5W1YTVN3GCK7B0EXA",
>     "signal": "cost",
>     "query": {
>       "metric": "genai.cost",
>       "filters": []
>     },
>     "condition": {
>       "comparator": "gt",
>       "threshold": 30,
>       "window": "15m",
>       "interval": "5m"
>     },
>     "notifier_ids": ["01JQ8Z1TF7QK9D2RH4NMV6PY3C"]
> }'
> ```
>
> > [!NOTE]
> >
> > The form derives `signal` from the chosen **Metric**, and the field is optional on create. When it is set over the API, use these values:
> >
> > | Preset | API `signal` value |
> > | - | - |
> > | Cost | `cost` |
> > | Latency | `latency` |
> > | Errors | `errors` |
> > | Guardrails | `evals` |
> > | Metric that maps to no single preset | `custom` |
>
> Alert routes are **Project** scoped, so a **Project** API key is sufficient.
>
> The API accepts two optional `condition` fields that the form does not expose:
>
> * `degraded_threshold`: opens a trigger at `degraded` severity before the critical threshold is reached. It must sit on the recovery side of `threshold`.
> * `resolve_threshold`: hysteresis. It defaults to the lowest configured tier and must sit at or past that tier on the recovery side. Use it to stop an alert flapping when a metric hovers at the threshold.
>
> Neither field is supported when `comparator` is `eq`.
>
> > [!NOTE]
> >
> > See the [API Reference](/docs/reference/alerts/create-an-alert.md) for the full parameter specification.

## **Condition Options**

| Setting | Values |
| - | - |
| **Trigger when value is** | `above` (`gt`), `at or above` (`gte`), `below` (`lt`), `at or below` (`lte`), `exactly` (`eq`) |
| **Over the last** | `5 minutes`, `15 minutes`, `30 minutes`, `1 hour`, `4 hours`, `1 day` |
| **Check frequency** | `Every 5 minutes`, `Every 15 minutes`, `Every hour`, `Every day` |

Thresholds are entered in each metric's own unit:

| Metric type | Unit | Example |
| - | - | - |
| Cost | US dollars | `30` means \$30 |
| Latency | Milliseconds | `2000` means 2 seconds |
| Pass rate, error rate | Percent | `95` means 95% |

> [!TIP]
>
> **Guardrail pass rate** and **Guardrail score (avg)** are the cases that call for a **below** comparator: a drop is the problem. Error rate needs **above**.

## **Filters**

In **AI Studio**, filters use the `is` and `is not` operators on the following fields:

**provider**, **model**, **identity**, **agent**, **deployment**, **evaluator**, **evaluator name**

The API accepts the operators `eq`, `neq`, `in`, and `not_in` on alert filters; see the [create an alert reference](/docs/reference/alerts/create-an-alert.md).

Each filter group uses a single field and a single operator. An **Alert** can carry up to 18 filters, or 16 on `genai.evaluator.score.avg`.

## **Alert Lifecycle**

An **Alert** runs on its check frequency and holds one of three statuses:

| Status | Meaning |
| - | - |
| `ok` | The last evaluation did not breach the threshold |
| `degraded` | The value crossed the warning tier set by `degraded_threshold` (API only) |
| `triggered` | The value crossed the threshold |

A breach opens a **trigger**, an incident record that stays open until the metric recovers and then closes as `resolved`. If the metric stops reporting entirely, the trigger resolves on its own once a full evaluation window plus the ingestion delay passes without data, and the next breach opens a fresh incident. This matters for metrics that only report while something runs, such as **Evaluators**. Notifications fire twice per incident: once when the trigger opens, once when it resolves. No repeat-notification interval exists, so a long-running incident will not flood an inbox.

Each trigger retains its supporting evidence, including the evaluated value, the threshold it crossed, and the runs that led there, making it possible to move from a notification to the **Traces** that caused it.

## **Managing Alerts**

> [tab] AI Studio
>
> From the **Alerts** list:
>
> * **Enable or disable** an **Alert**. A disabled **Alert** stops evaluating but keeps its trigger history.
> * **Duplicate** an **Alert** as the starting point for a variant. Duplicates are created disabled, allowing the threshold to be adjusted before it fires.
> * **Edit** any field except the **Project**.
> * **Delete** an **Alert** along with its history.
>
> Filter the list by status, enabled state, and type. Threshold alerts are currently the only type.

> [tab] API / SDK
>
> | Operation | Endpoint | SDK method |
> | - | - | - |
> | Create an alert | `POST /v2/alerts` | `alerts.create` |
> | List alerts | `GET /v2/alerts` | `alerts.list` |
> | Retrieve an alert | `GET /v2/alerts/{alert_id}` | `alerts.get` |
> | Update an alert | `PATCH /v2/alerts/{alert_id}` | `alerts.update` |
> | Delete an alert | `DELETE /v2/alerts/{alert_id}` | `alerts.delete` |
> | List triggers | `GET /v2/alerts/{alert_id}/triggers` | `alerts.listTriggers` |
> | List trigger events | `GET /v2/alerts/{alert_id}/triggers/{trigger_id}/events` | `alerts.listTriggerEvents` |
>
> List endpoints paginate with `limit` (1 to 200, default 25) plus the `starting_after` and `ending_before` cursors. `GET /v2/alerts` also accepts `project_id`.
>
> ```bash cURL theme={"theme":{"light":"github-light","dark":"github-dark"}}
> curl --location 'https://router.toqan.ai/eu/v2/alerts/01JQ8Z2K4M6P8R0T2V4X6Z8B0D' \
> --request PATCH \
> --header "Authorization: Bearer $TOQAN_API_KEY" \
> --header 'Content-Type: application/json' \
> --data-raw '{"enabled": false}'
> ```

## **Plan Limits**

The number of **Alerts** and the minimum check frequency depend on the active plan:

| Plan | Max alerts | Fastest check frequency |
| - | - | - |
| Free (Pay as you go without a payment method on file) | 2 | Every hour |
| Pay as you go | 10 | Every 5 minutes |
| Enterprise | 20 | Every 5 minutes |

Saving an **Alert** with a frequency below the plan minimum returns `evaluation interval 5m is below your plan's minimum of 1h0m0s`.

## **Next Steps**

> [card] [Traces](/docs/ai-studio/observability/traces.md)
>
> Investigate the requests behind a trigger.

> [card] [Automations](/docs/ai-studio/observability/automations.md)
>
> Act on matching traces automatically instead of only notifying.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.