Skip to content

Alert rules

An alert rule decides when PathWatch notifies you. Each rule combines:

  • a scope — which monitors the rule watches,
  • a condition — what has to happen,
  • a confirmation block — how sure PathWatch must be before firing,
  • a notifications block — recovery notices and recurring reminders,
  • one or more channel bindings — where the alert goes, each with an optional escalation delay.

Create and edit rules in the WebUI at Alerts → Rules, or via the API (POST /api/v1/alert-rules). A rule also carries a name (required), an optional description, and an enabled flag — disable a rule to mute it without deleting its configuration.

Scope

A rule watches one monitor, a tagged group, or everything in the organisation:

Scope typeFieldsWatches
monitormonitor_idA single monitor.
monitor_grouptagEvery monitor carrying the tag. Monitors added to the tag later are covered automatically. See Monitor groups.
all_monitorsEvery monitor in the organisation, including ones created after the rule.

A monitor can match any number of rules; each rule evaluates independently on every check result.

Conditions

Seven condition types are available. Each rule has exactly one condition.

ConditionFieldsFires when
status_changeto (list of statuses, at least one)A check reports any status in to. Statuses: up, down, degraded, timeout. An optional from list is accepted by the API but the current evaluator matches on to only.
metric_thresholdmetric, operator, thresholdThe named metric crosses the threshold. operator is one of gt, lt, eq, neq, gte, lte.
ssl_expirydays_before (≥ 1)The monitored certificate has days_before or fewer days until expiry. Use with SSL monitors.
domain_expirydays_before (≥ 1)The monitored domain registration has days_before or fewer days remaining. Use with domain expiration monitors.
keyword_missingkeywordThe response body does not contain the keyword.
certificate_changedA check detects that the certificate serving the endpoint changed since the previous check.
monitoring_unavailableThe check could not run at all — no runner or region was available to execute it. This alerts on monitoring coverage, not on your service.

Metric names for metric_threshold

response_time (alias duration_ms) compares against the check’s total duration in milliseconds. Any other numeric field from the check’s result data also works — for example ssl_days_remaining on SSL checks or packet_loss_pct on ping checks. See the result data tables on each monitor type’s page for the fields it produces.

Confirmation

The confirmation block controls how much evidence the rule needs before it fires:

FieldDefaultMeaning
consecutive_failures1The condition must hold for this many checks in a row before the alert fires.
confirmation_regionsnullComing soon. Will restrict which regions’ results count toward confirmation. The field is accepted and stored today, but does not yet affect evaluation — consecutive_failures is the active control.

Failure counts are tracked per region: each (rule, monitor, region) combination keeps its own consecutive-failure counter and its own alerting state, so a wobble in one region doesn’t inherit the count from another. A single passing check from a region resets that region’s counter and recovers its alert.

For tuning advice — thresholds by check interval, multi-region confirmation patterns, and the trade-offs — see Confirmation regions & failure thresholds.

Notifications

FieldDefaultMeaning
on_recoverytrueSend a recovery notice to the rule’s channels when the alert clears.
recurringfalseKeep re-sending the alert while it stays active and unacknowledged.
recurring_interval_minutesnullMinutes between recurring reminders (≥ 1). Required for recurring to take effect.

Recurring reminders fire to every channel bound to the rule (including escalation-delayed ones), and stop the moment the alert is acknowledged or recovers. Recovery notices likewise go to every bound channel.

Channel bindings and escalation delays

Each rule carries a list of channel bindings:

FieldDefaultMeaning
channel_idAn alert channel to notify.
delay_minutes0How many minutes after the alert starts before this channel is notified. 0 = immediately.

Bindings with different delays form an escalation chain: page the team Slack immediately, then PagerDuty 15 minutes later if nobody has acknowledged. A delayed channel never fires if the alert recovers or is acknowledged before its delay elapses. Full behaviour — timing, acknowledgement, recovery interplay — is on the Alert escalation page.

Acknowledging alerts

The Active alerts panel at the top of Alerts lists every currently firing (rule × monitor × region) row. Acknowledging a row stops escalation steps and recurring reminders for that alert; it does not resolve the alert or notify anyone. Acknowledgement is per-region — you can silence one region’s alert while others keep escalating — and re-acknowledging an already-acknowledged alert is harmless.

Via the API: POST /api/v1/alert-rules/:id/acknowledge with {"monitor_id": "...", "region": "..."} (omit region to target the monitor-wide alert state).

Every delivery — initial alert, escalation, reminder, recovery, acknowledgement — is recorded in Alerts → History with the channel, timestamp, and delivery status.

Plan limits

FreeStarterProBusiness
Alert rules10152550
Alert channels5102050

See Limits & quotas for the full plan comparison.

Examples

The JSON below matches the POST /api/v1/alert-rules request body. Replace <...-channel-id> with real channel ids from Alerts → Channels.

Simple down alert

Fire on the first failed check, notify by email, send a recovery notice:

{
"name": "API down",
"scope": { "type": "monitor", "monitor_id": "<monitor-id>" },
"condition": { "type": "status_change", "to": ["down", "timeout"] },
"confirmation": { "consecutive_failures": 1, "confirmation_regions": null },
"notifications": { "on_recovery": true, "recurring": false, "recurring_interval_minutes": null },
"channels": [
{ "channel_id": "<email-channel-id>", "delay_minutes": 0 }
],
"enabled": true
}

Multi-region confirmed alert

Require two consecutive failures, counted only from the listed regions, before paging — a single-region blip stays quiet:

{
"name": "Checkout down (confirmed)",
"scope": { "type": "monitor_group", "tag": "checkout" },
"condition": { "type": "status_change", "to": ["down"] },
"confirmation": {
"consecutive_failures": 2,
"confirmation_regions": ["us-virginia", "gb-london"]
},
"channels": [
{ "channel_id": "<slack-channel-id>", "delay_minutes": 0 }
]
}

Escalation chain (0 min → 15 min)

Slack immediately; PagerDuty only if the alert is still firing and unacknowledged 15 minutes later:

{
"name": "Production outage escalation",
"scope": { "type": "all_monitors" },
"condition": { "type": "status_change", "to": ["down", "timeout"] },
"confirmation": { "consecutive_failures": 2, "confirmation_regions": null },
"notifications": { "on_recovery": true, "recurring": false, "recurring_interval_minutes": null },
"channels": [
{ "channel_id": "<slack-channel-id>", "delay_minutes": 0 },
{ "channel_id": "<pagerduty-channel-id>", "delay_minutes": 15 }
]
}

Recurring reminder

Re-notify every 30 minutes while the monitor stays down and nobody has acknowledged:

{
"name": "Keep paging until acknowledged",
"scope": { "type": "monitor", "monitor_id": "<monitor-id>" },
"condition": { "type": "status_change", "to": ["down"] },
"notifications": {
"on_recovery": true,
"recurring": true,
"recurring_interval_minutes": 30
},
"channels": [
{ "channel_id": "<pushover-channel-id>", "delay_minutes": 0 }
]
}