---
title: Notification channels
description: All 16 channel types, what each needs, how alerts are routed, grouped and tested, and how to add a channel.
canonical: https://watchfor.io/docs/notifications
---

# Notification channels

All 16 channel types, what each needs, how alerts are routed, grouped and tested, and how to add a channel.

A **notification channel** is a destination for incident alerts — an inbox, a
chat room, a pager, a push app or an HTTP endpoint. When a confirmed
[incident](/docs/alerting/incidents) opens, and again when it resolves,
WatchFor delivers to every channel the affected monitor routes to. Channels are
managed under **Alerting → Channels & contacts** by owners and admins; members can see the
list and send a test to a channel, but can't add, edit, disable or delete one
(see [members & roles](/docs/organization)).

## Channel types

WatchFor ships **16 channel types**. *What you need* is what the **Add Channel**
form asks for; *Delivery* says whether a burst of incidents arrives as one
summary message or one message per incident (see
[grouping](#grouping-during-a-storm)).

| Channel | What you need | Delivery | Guide |
| --- | --- | --- | --- |
| **Email** | One or more contact groups (recipients come from their contacts) | Grouped | [Email](/docs/notifications/email) |
| **Slack** | Incoming-webhook URL; optional channel, bot name, icon emoji | Grouped | [Slack](/docs/notifications/slack) |
| **Discord** | Webhook URL; optional bot name, avatar URL | Grouped | [Discord](/docs/notifications/discord) |
| **Telegram** | Chat ID — the official bot tells you yours | Grouped | [Telegram](/docs/notifications/telegram) |
| **Microsoft Teams** | Workflows webhook URL | Grouped | [Microsoft Teams](/docs/notifications/teams) |
| **Google Chat** | Space webhook URL | Grouped | [Chat apps](/docs/notifications/chat-apps#google-chat) |
| **Mattermost** | Incoming-webhook URL; optional channel, bot name | Grouped | [Chat apps](/docs/notifications/chat-apps#mattermost) |
| **Rocket.Chat** | Incoming-webhook URL; optional channel, bot name | Grouped | [Chat apps](/docs/notifications/chat-apps#rocketchat) |
| **ntfy** | Topic; optional server URL and access token | Per incident | [ntfy](/docs/notifications/ntfy) |
| **Gotify** | Server URL, application token | Per incident | [Push apps](/docs/notifications/push#gotify) |
| **Pushover** | API token, user or group key | Per incident | [Push apps](/docs/notifications/push#pushover) |
| **Pushbullet** | Access token | Per incident | [Push apps](/docs/notifications/push#pushbullet) |
| **PagerDuty** | Events API v2 routing key; region (US / EU) | Per incident, opens and resolves | [PagerDuty](/docs/notifications/pagerduty) |
| **Opsgenie** | API integration key; region (US / EU) | Per incident, opens and closes | [Opsgenie](/docs/notifications/opsgenie) |
| **Webhook** | HTTPS URL; optional HMAC secret | Per incident, signed JSON | [Webhooks](/docs/notifications/webhooks) |
| **Zapier** | Catch Hook URL | Per incident, flat JSON | [Webhooks](/docs/notifications/webhooks#zapier) |

SMS is not offered yet. For paging *individual people* through their own
methods rather than a shared channel, see
[personal notification methods](/docs/alerting/on-call#personal-notification-methods)
under on-call.

## Adding a channel

### Open Alerting → Channels & contacts
Click **Add Channel**, give the channel a name (unique per type) and pick a
type from the grid.

### Fill in the channel's details
The form shows only the fields that type needs — a webhook URL, a token, a
chat ID… Most types include a short pointer to where the value lives in the
other tool, and every guide linked above walks through it.

### Choose contact groups
Under **Alert Routing**, tick one or more
[contact groups](/docs/notifications/contact-groups). The channel delivers
alerts for every monitor whose **Notification Targets** include one of those
groups. Email channels require at least one group; for other types it is how
the channel gets any traffic at all.

### Pick a severity filter and save
**Critical** and **Warning** are both on by default; untick one to keep, say,
warnings off the pager. Switch **Enabled** off to keep a channel configured
but silent.

### Send a test
On the channel's row open **⋯ → Send test**. A clearly marked `[TEST]`
notification goes out immediately, bypassing grouping. A short cooldown
applies between tests of the same channel (longer on the free plan).

> **Tests reach real tools**
>
> A test to **PagerDuty** or **Opsgenie** opens a real incident/alert there
> (titled `[TEST]`) that you close by hand — WatchFor never sends a resolve
> for a test. A test to a **webhook** arrives with `incident.id` = `0`.

### Guard rails on save

- **Duplicates.** Two channels of the same type can't share a name. A channel
  with the same webhook URL, the same contact groups *and* the same severity
  filter as an existing one is rejected outright (it would double-notify).
  The same URL with different routing shows a warning you can accept.
- **Delivery URLs are checked.** A URL must use `http://` or `https://` and
  point at a host on the public internet. Private, loopback and link-local
  addresses (`10.x`, `172.16–31.x`, `192.168.x`, `127.x`, `169.254.x`,
  `::1`, `fe80::`) and WatchFor's own domains are rejected when you save —
  and again at send time, so a hostname that later resolves to a private
  address is refused too. Self-hosted ntfy, Gotify, Mattermost or Rocket.Chat
  servers therefore need a public address.
- **A rejected save says why, in words.** When the server refuses a value the
  explanation appears under the field it belongs to, with a short
  *Couldn't save channel* toast — never raw validation output.
- **Secrets stay secret.** Tokens, keys and webhook URLs are stored encrypted,
  masked in the dashboard and never returned by the API. When you edit a
  channel, a stored secret shows as a blank *leave blank to keep current*
  field — save without retyping and the stored value is kept.

## How routing works

Routing is derived from two things you already maintain; there is no separate
rules table to keep in sync:

1. Every monitor has **Notification Targets** (its **Alerting** tab): one or
   more contact groups. A new monitor is attached to your
   [default group](/docs/notifications/contact-groups#the-default-group)
   automatically.
2. Every channel is attached to one or more contact groups.

When an incident fires, WatchFor notifies **every enabled channel attached to
any of the monitor's groups**, then applies each channel's severity filter.
Changing a monitor's targets, a channel's groups or a severity filter takes
effect immediately — no restart, no redeploy.

Two tools help you confirm the wiring:

- The dashboard's **Silent Monitors** card lists monitors whose incidents would
  reach no channel.
- **Test notifications** on a monitor's page (⋯ menu) sends a synthetic alert
  through the exact channels resolved for that monitor and reports what each
  one did.

## The default channel

Every organization is bootstrapped with an email channel named
**Default Email — *your organization*** that delivers to the owner's address
through the default contact group, flagged **Default** in the list. It exists
so a fresh account's first critical alert never lands nowhere.

- The default channel **can't be deleted**. Promote another channel first
  (**⋯ → Set as default**), then delete the old one.
- It can be edited, re-routed or **disabled** like any other channel.
- There is always exactly one default channel per organization.

## What a notification contains

Notifications go out only for **confirmed** incidents — a single failed
location shows the monitor as *Degraded* in the dashboard but doesn't page
anyone (see [how incidents work](/docs/alerting/incidents)). While a critical
incident is open on a monitor, that monitor's warning alerts are held back —
no separate warning incident and no warning message — until the critical one
resolves (see [Critical outranks warning](/docs/alerting/incidents#critical-outranks-warning)).
The title of every message reflects the rule's severity and the incident's
state:

| Event | Title |
| --- | --- |
| Critical rule fires | 🔴 **DOWN: *monitor name*** |
| Warning rule fires | 🟡 **Degraded: *monitor name*** |
| Recovery | 🟢 **UP: *monitor name*** |
| Closed administratively (rule disabled, monitor paused, resolved by a person) | ⏹️ **Resolved: *monitor name*** — with who and why |

The body carries the full story, rendered natively for each channel: a
plain-language **diagnosis** ("Unexpected HTTP Status"), **Expected** vs
**Detected** values (and *Now Returning* on recovery), the target, severity,
start and resolve times, incident duration, the **locations that confirmed**
the failure, a flapping flag when state changes rapidly, certificate details
for SSL incidents, the rule version in effect if the rule changed
mid-incident, and a link straight to the incident.

## Grouping during a storm

When one failure takes several monitors down at once, chat and email channels
receive **one summary per channel** instead of a message per incident:

> 🔴 **5 new incidents**
> 🔴 api.example.com — Probe failed to connect
> 🔴 www.example.com — Unexpected HTTP Status
> …

- The **first message about an incident** on a channel is sent after at
  most **30 seconds**, together with any other incidents that fire in that
  window — a lone incident still arrives promptly as a normal, fully
  detailed message; grouping only kicks in when several land together. This
  holds even when the channel has just delivered something else: a new
  outage never waits behind an earlier notification.
- **Follow-ups** about an incident the channel has already delivered — its
  recovery, a repeat reminder — are batched for up to **5 minutes** after
  the previous message on that channel and arrive as one more summary, so
  a slowly developing outage doesn't drip one message per wave. A new
  incident arriving meanwhile sends the pending follow-ups along with it.
- After 5 minutes without messages about an incident, its next message is
  treated as new again — a recovery after a long outage goes out within
  30 seconds.
- An incident that opened while its monitor was **muted or under
  maintenance** and is still open when that ends gets its first message
  within about a minute of the silence lifting (not on the next repeat
  reminder); an acknowledged one stays quiet.
- Recoveries group the same way (🟢 **4 recovered**); a mixed window lists
  new incidents first, then recoveries. Summaries show up to 10 lines, then
  "…and N more".
- Grouping applies to **Email, Slack, Discord, Telegram, Teams, Google Chat,
  Mattermost and Rocket.Chat**. PagerDuty and Opsgenie stay one event per
  incident (their open/close lifecycle depends on it), webhooks and Zapier
  stay one payload per incident, and push apps deliver per incident.
- [Notification history](/docs/notifications/history) still records one row
  per incident, even when several were delivered in one message.

## Repeat reminders

WatchFor notifies once when an incident opens and once when it resolves. If
you want to be nagged while something stays down, enable **Repeat reminders
while down** on the monitor's Alerting tab — see
[alert rules](/docs/alerting#repeat-reminders). Reminders stop as soon as the
incident is acknowledged or resolves.

## Muting a monitor

Need quiet without stopping the checks? **Mute alerts** from the monitor's
**⋯ menu** for 1 hour, 8 hours, 24 hours or 7 days. While muted:

- checks keep running and incidents keep opening, closing and recording
  history — only outbound notifications are suppressed, and each suppressed
  delivery is recorded as **Silenced** in
  [notification history](/docs/notifications/history);
- the monitor shows a **Muted** badge on its page and in the monitors list,
  and a **Muted** filter finds every silenced monitor;
- you can mute and unmute from a firing incident's header too;
- this differs from **Pause**, which stops the checks themselves, and from a
  [maintenance window](/docs/monitors/maintenance), which is scheduled and
  can also exclude the period from uptime.

Muting needs the owner or admin role and is recorded in the
[activity log](/docs/organization/activity-log).

## Also via API

Channels are configured in the dashboard. Everything around them is available
to scripts and AI agents: [contacts and contact groups](/docs/api/contacts)
via the REST API, and the delivery log via `GET /v1/notifications` (see the
[resource list](/docs/api#resources)), the MCP tool `list_notifications`
([MCP server](/docs/api/mcp)) and A2A.

---

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