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

# Notification Policies

> Configure DevHelm notification policies to route alerts based on severity, monitors, regions, and conditions

Notification policies control which incidents trigger which alert channels. Each policy combines match rules (what to alert on) with an escalation chain (how to alert).

<Tip>
  **Define this in code.** Manage notification policies as part of your monitoring-as-code workflow:
  [YAML format](/mac/yaml/alerting) · [Terraform](/mac/terraform/alerting) · [CI/CD patterns](/mac/ci-cd/overview)
</Tip>

## How matching works

When an incident is confirmed, DevHelm evaluates all enabled notification policies in **priority order** (highest priority first). **All matching policies execute** — there is no "first match wins" behavior.

A policy matches when **all** of its match rules pass (AND logic). A policy with no match rules is a **catch-all** that matches every incident.

## Match rules

Each match rule filters incidents on a specific attribute:

| Rule type              | Matches on                                        | Value field              |
| ---------------------- | ------------------------------------------------- | ------------------------ |
| `severity_gte`         | Incident severity at or above the specified level | `value` (e.g., `"DOWN"`) |
| `monitor_id_in`        | Specific monitor IDs                              | `monitorIds`             |
| `monitor_type_in`      | Monitor types (HTTP, TCP, DNS, etc.)              | `values`                 |
| `monitor_tag_in`       | Monitor tags                                      | `values`                 |
| `region_in`            | Affected probe regions                            | `regions`                |
| `incident_status`      | Incident event type (created, resolved, reopened) | `value`                  |
| `service_id_in`        | Status Data service IDs                           | `values`                 |
| `resource_group_id_in` | Resource group IDs                                | `values`                 |
| `component_name_in`    | Service component names                           | `values`                 |

### Severity ordering

Severity comparison uses: `DOWN` > `DEGRADED` > `MAINTENANCE`. A `severity_gte` rule with value `DEGRADED` matches both `DOWN` and `DEGRADED` incidents but not `MAINTENANCE`.

### Match rule fields

| Field        | Type      | Description                                                       |
| ------------ | --------- | ----------------------------------------------------------------- |
| `type`       | string    | Rule type from the table above                                    |
| `value`      | string    | Single-value match (for `severity_gte`, `incident_status`)        |
| `monitorIds` | UUID\[]   | Monitor IDs for `monitor_id_in`                                   |
| `regions`    | string\[] | Region codes for `region_in`                                      |
| `values`     | string\[] | Multi-value match (for `monitor_type_in`, `monitor_tag_in`, etc.) |

## Priority

The `priority` field (integer, default `0`) controls evaluation order. Higher values are evaluated first. While all matching policies run, priority determines which escalation chains start first when multiple policies match simultaneously.

Use priority to structure a tiered alerting strategy:

| Priority | Policy               | Purpose                                    |
| -------- | -------------------- | ------------------------------------------ |
| 100      | Critical — PagerDuty | Page on-call for `DOWN` incidents          |
| 50       | Warning — Slack      | Post to a channel for `DEGRADED` incidents |
| 0        | Catch-all — Email    | Email summary for everything else          |

## Creating a policy

The CLI covers the simple case: a policy that notifies one or more channels immediately. For priority, match rules, and multi-step escalation, use the API (below) or [YAML config-as-code](/mac/yaml/alerting).

<CodeGroup>
  ```bash CLI theme={null}
  devhelm notification-policies create \
    --name "Critical alerts" \
    --channel-ids "<slack-id>,<pagerduty-id>"
  ```

  ```bash API theme={null}
  curl -X POST https://api.devhelm.io/api/v1/notification-policies \
    -H "Authorization: Bearer $DEVHELM_API_TOKEN" \
    -H "Content-Type: application/json" \
    -d '{
      "name": "Critical alerts",
      "priority": 100,
      "matchRules": [
        {
          "type": "severity_gte",
          "value": "DOWN"
        }
      ],
      "escalation": {
        "steps": [
          {
            "delayMinutes": 0,
            "channelIds": ["<slack-channel-id>"]
          },
          {
            "delayMinutes": 5,
            "channelIds": ["<pagerduty-channel-id>"],
            "requireAck": true,
            "repeatIntervalSeconds": 300
          }
        ],
        "onResolve": "notify_all_steps",
        "onReopen": "restart_from_beginning"
      }
    }'
  ```
</CodeGroup>

### Request fields

| Field        | Type            | Required | Default          | Description                       |
| ------------ | --------------- | -------- | ---------------- | --------------------------------- |
| `name`       | string          | Yes      | —                | Human-readable name               |
| `matchRules` | MatchRule\[]    | No       | `[]` (catch-all) | Filtering rules                   |
| `escalation` | EscalationChain | Yes      | —                | Steps, channels, and behavior     |
| `enabled`    | boolean         | No       | `true`           | Whether the policy is active      |
| `priority`   | integer         | No       | `0`              | Evaluation order (higher = first) |

## Catch-all policies

A policy with an empty `matchRules` array matches every incident. Use a low-priority catch-all as a safety net:

```json theme={null}
{
  "name": "Catch-all — Email digest",
  "priority": 0,
  "matchRules": [],
  "escalation": {
    "steps": [{
      "delayMinutes": 0,
      "channelIds": ["<email-channel-id>"]
    }]
  }
}
```

## Testing a policy

Dry-run match rules against a hypothetical incident to verify routing before real incidents arrive:

```bash theme={null}
curl -X POST https://api.devhelm.io/api/v1/notification-policies/<policy-id>/test \
  -H "Authorization: Bearer $DEVHELM_API_TOKEN"
```

## Policy fields

| Field        | Type            | Description                           |
| ------------ | --------------- | ------------------------------------- |
| `id`         | UUID            | Unique policy identifier              |
| `name`       | string          | Human-readable name                   |
| `matchRules` | MatchRule\[]    | All must pass for a match (AND logic) |
| `escalation` | EscalationChain | Ordered alert steps                   |
| `enabled`    | boolean         | Whether the policy is active          |
| `priority`   | integer         | Evaluation order (higher = first)     |

## Next steps

<CardGroup cols={2}>
  <Card title="Escalation chains" icon="arrow-up-right-dots" href="/alerting/escalation-chains">
    Build multi-step escalation with delays and acknowledgment.
  </Card>

  <Card title="Alert channels" icon="plug" href="/alerting/channels">
    Configure the destinations referenced by escalation steps.
  </Card>

  <Card title="Alert suppression" icon="bell-slash" href="/alerting/suppression">
    Suppress alerts during maintenance and via resource groups.
  </Card>
</CardGroup>
