---
title: Alert rules & severities in WatchFor
description: How WatchFor decides a check result is a problem — system rules, per-type presets, severities, confirmation settings, reminders and what a match triggers.
canonical: https://watchfor.io/docs/alerting
---

# Alert rules & severities in WatchFor

How WatchFor decides a check result is a problem — system rules, per-type presets, severities, confirmation settings, reminders and what a match triggers.

A monitor *watches*; an **alert rule** decides what counts as a problem. Rules
live on each monitor's **Alerting** tab; owners and admins manage them, members
can view them (see [members & roles](/docs/organization)). This page explains
the parts of a rule, what you get without
configuring anything, and the settings that control how a rule turns into an
[incident](/docs/alerting/incidents).

**Also via API:** rules can be listed, created, updated, toggled and deleted
through the [REST API](/docs/api/alert-rules), the MCP server and A2A.

## What you get automatically

Every new monitor is created with **system rules** so incidents, status and
uptime work from the first check:

- an **Availability Check** (critical) — "the target is unreachable: DNS,
  connection, TLS or timeout error" — for every type except domain expiry
  and heartbeat, which have their own signal;
- **type defaults**, for example *Unexpected Status Code* (HTTP), *HTTP
  Status Evaluation*, *Assertions Failed* and a 30-day *SSL Expiry Warning*
  (API), *SSL Expiry Warning* at 14 days (SSL), *Missed Schedule* and *Run
  Failed* (heartbeat), *Domain Expiry* at 30 days (domain), *Open Relay
  Detected* (SMTP), *Certificate Expiring* (IMAP, POP3), *Message Not
  Delivered* and *Landed in Spam* (email round-trip), *SPF / DMARC Record
  Missing* (email policy), *Listed on
  Any RBL* (blacklist), *LCP / CLS Poor* (Core Web Vitals), *Tool
  Inventory Changed* and *No Tools Exposed* (MCP), and so on.

System rules can be switched on or off and their thresholds tuned, but not
deleted. Each new monitor's notification target is your default contact
group, so the first alert already has somewhere to go.

## Presets, not blank pages

The Alerting tab lists **presets** for the monitor's type. Each preset is a
ready-made rule — metric, comparison and a sensible default threshold — that
you switch on and adjust. A few examples:

| Type | Presets (defaults) |
| --- | --- |
| **HTTP** | Probe Status · HTTP Status Evaluation (anything outside 2xx/3xx) · Response Time (warning 2 s / critical 5 s) · Response Body Match · SSL Certificate (under 14 days) |
| **API** | Probe Status · HTTP Status Evaluation · Assertions Failed · Response Time |
| **Ping** | Probe Status · Packet Loss (> 50 %) · Ping Latency (> 200 ms) |
| **DNS** | Probe Status · DNS Lookup Time · No Records Returned · DNS Errors · Expected DNS Records |
| **TCP** | Probe Status · TCP Connect Time · TLS Handshake Time · Response Match |
| **SSL / TLS** | Probe Status · Certificate Expiry · Hostname Match · Certificate Chain · Minimum TLS Version · TLS Grade |
| **Heartbeat** | Missed Schedule · Run Failed · Specific Exit Code · Run Duration |
| **MCP** | Status (Up / Down) · Tool Inventory Changed · No Tools Exposed · Slow Handshake · Protocol Version Mismatch · SSL Certificate |
| **Core Web Vitals** | Audit Status · LCP · CLS · Performance Score · SEO Score |
| **Network path (MTR)** | Probe Status · Destination Unreachable · Destination Packet Loss · Destination RTT · Loss At Any Hop · Unresponsive Hops |

Every other type — UDP, NTP, SMTP, IMAP, POP3, email round-trip, FTP, SFTP, WebSocket, email policy, domain
expiry, CDN, Brotli, CMS, sitemap, favicon, blacklist, data breach — has its
own set; the type pages under [Monitors](/docs/monitors) list what each one
can alert on. When only one preset makes sense for a type, it is expanded for
you.

Some presets create **two rules at once** — a warning and a critical
threshold for the same metric (response time, Core Web Vitals scores, host
CPU / memory / disk, certificate and domain expiry). Certificate and domain
expiry start with the warning level only: their critical level is off until
you switch it on, because a critical expiry incident marks the monitor Down
and counts as downtime. Each
level has its own switch next to its slider, so you can keep only the
critical page, only the warning heads-up, or both; a level you switch off
stays visible, dimmed, with its threshold kept. When
both match, only the critical one fires, so you never get two incidents for
one slow response. The same rule applies across a monitor: while a critical
incident is open, its warning alerts are held back until it resolves — see
[Critical outranks warning](/docs/alerting/incidents#critical-outranks-warning).

**Probe Status** (or *Availability Check*) is **locked**: it is the rule that
makes the monitor's Up/Down status and uptime meaningful, so it cannot be
disabled.

## Anatomy of a rule

| Part | Meaning |
| --- | --- |
| **Metric** | What is measured: HTTP status code, response time, certificate days remaining, packet loss, a type-specific value such as `metrics['mcp.tools_count']`… |
| **Comparison & threshold** | `>`, `<`, `==`, "not in 2xx/3xx", a regex match — against the value you set |
| **Severity** | Critical or Warning (below) |
| **Confirmation threshold** | Consecutive failed checks before the rule fires (monitor-wide, see below) |
| **Locations that must agree** | Distinct locations that must see the failure before it fires. Default 1; adjustable through the [API](/docs/api/alert-rules) (`min_failed_probes`) |
| **Notification target** | The contact group(s) the monitor notifies; a rule can override it |

### How a check result is evaluated

Rules are evaluated on every check result, including failed ones:

- The **availability rule** (*Probe Status*) always runs — it decides whether
  the target could be reached at all.
- A **metric rule** runs only when its metric is present in that result. A
  failed check still carries whatever the probe managed to measure — an MTR
  trace that never reached the destination, a DNS lookup that came back with
  an error — so rules on those values (*Destination Unreachable*, *DNS
  Errors*) fire alongside the availability rule. A metric the probe could not
  measure (no status code without a response, no certificate without a
  handshake) leaves its rules untouched: they neither fire nor resolve on that
  result.
- **Response-time rules never fire on a failed check.** A timeout is
  reported by the availability rule, not as "slow".

## Severity

Every rule has a severity. It flows through to the monitor's status, your
channels, on-call and the status page:

	- [🔴 Critical](#): A hard failure — unreachable, wrong status code, invalid certificate, missed cron run. A confirmed critical incident shows the monitor as **Down** and is the only severity that pages the on-call chain.
	- [🟠 Warning](#): Worth knowing — slow responses, a certificate expiring soon, packet loss, low-priority observations such as "sitemap has fewer URLs than expected". The monitor shows **Degraded**; channels are notified, on-call is not paged.

Each notification channel has its own **severity filter**, so a PagerDuty
channel can take criticals only while Slack gets both — see
[Notifications](/docs/notifications#adding-a-channel).

## Confirmation settings

Below the presets, the Alerting tab has monitor-wide settings that apply to
all of the monitor's rules:

| Setting | Default | What it does |
| --- | --- | --- |
| **Confirmation threshold** | 3 consecutive failures (1 for heartbeat) | How many failed checks in a row are needed before an incident opens. While a failure is being confirmed the monitor shows **Degraded**; re-checks run on an accelerated schedule from the monitor's locations — see [how a failure becomes an incident](/docs/monitors/scheduling#how-a-failure-becomes-an-incident). Range **1–10** (heartbeat: 1–10 missed windows). The slider explains the trade-off: 1 alerts on the first confirmed failure — fastest, most false alarms; 3 (the default) balances speed and noise; higher means fewer false alarms and slower alerts. |
| **Duration window** | Off | How long the condition must persist before notifications are sent, up to 60 minutes. Off means "as soon as the confirmation threshold is reached". |
| **Notification targets** | Your default contact group | The contact groups whose channels (and escalation policy) receive this monitor's alerts. **Flow** opens a read-only picture of the whole path: channels, then the escalation chain with who is on call now. |
| **Repeat reminders while down** | Off | See below. |

Recovery is symmetric: an incident resolves after **three consecutive
successful checks**, so a single lucky response does not close a real outage.
Domain expiry, SSL certificate, breach, blocklist and heartbeat monitors
close on **one** healthy check — their answers do not flap and their checks
run far apart. The Alerting tab says which applies under the confirmation
threshold; the full list is in
[Resolving incidents](/docs/alerting/resolving#automatic-resolution-recovery).

Changes are tracked: every edit creates a new **version** of the rule, and an
incident always shows the version that was in effect when it fired — see
[Root cause analysis](/docs/alerting/root-cause#why-the-rule-version-matters).

## What happens when a rule matches

1. The first failing check puts the monitor in **Degraded** and starts the
   accelerated confirmation re-checks.
2. When the confirmation threshold (and duration window, if set) is met, an
   **incident** opens — **Down** for critical, **Degraded** for warning — and
   notifications go to the monitor's targets. Critical incidents also start
   the [escalation policy](/docs/alerting/on-call), if one is attached.
3. Checks keep running faster than normal until the incident resolves, then
   return to the regular interval.

Disabling or deleting a rule that has an open incident **resolves that
incident** with the reason recorded, so nothing stays "firing" for a rule
that no longer exists. Pausing a monitor does the same for all of its
incidents. See [Resolving incidents](/docs/alerting/resolving).

## Repeat reminders

By default WatchFor notifies **once** when an incident opens and once when it
resolves — no repeat spam. If you would rather be reminded while something
stays broken, set **Repeat reminders while down** on the monitor's Alerting
tab to every 1, 6, 12 or 24 hours. Reminders stop the moment the incident is
[acknowledged](/docs/alerting/incidents#acknowledging) or resolves, so you are
never chased about something you are already on.

### Expiry reminders

Certificate and domain expiry incidents can also remind you on chosen
**days left** instead of on a clock: **Remind me again at** on the expiry card
(for example 14 and 3) re-sends the open incident's notification once when
that many days remain, unless it has been acknowledged. Both settings can be
on at once; a reminder that falls on the same refresh as a repeat goes out as
one notification. See
[Expiry levels and reminders](/docs/monitors/certificates#expiry-levels-and-reminders).

## Related

	- [How incidents work](/docs/alerting/incidents): The lifecycle from confirmed failure to resolution, and what an incident page shows.
	- [Notifications](/docs/notifications): Channels, severity filters, grouping during a storm, muting.
	- [On-call & escalations](/docs/alerting/on-call): Page a person, not a channel, until someone acknowledges.
	- [Alert rules API](/docs/api/alert-rules): Create and tune rules from scripts and AI agents.

---

Canonical page: https://watchfor.io/docs/alerting · All docs: https://watchfor.io/docs · Site guide: https://watchfor.io/llms.txt
