Alert channels

Where an alert goes. Each notification group can have several, each with its own minimum severity and its own quiet hours.

Available now

CHANNELDESTINATIONSECRETNOTE
EmailAn email addressNone — the central sends through its own SMTPThe fallback when a host has no notification group: ALERT_MAIL_TO.
SMSA phone numberIn the installation config, not per customerNeeds an SMS gateway configured on the installation. Best used with a minimum severity of critical.
WebhookAn https URL you controlOptional signing key, stored encryptedOur own JSON, versioned, with the whole batch in one request and an HMAC-SHA256 signature over the raw body. This is the one that covers Discord, Teams, Zapier and n8n.
ntfyhttps://ntfy.sh/your-topic, or your own serverOptional tokenThe body is the text; title, priority and tags are headers.
Gotifyhttps://gotify.example/messageApplication tokenSelf-hosted push. Needs ALERT_WEBHOOK_ALLOW_PRIVATE if it runs on your LAN.
SlackAn incoming webhook URLThe URL is the secretShown masked everywhere, because the URL alone is write access to the channel.
MattermostAn incoming webhook URLThe URL is the secretSame body as Slack.
Home Assistant/api/webhook/<id>The webhook id is the secretThe webhook route only. We will not store a long-lived token: that is control over the whole installation.
PushbulletA device, or all of themAccess tokenThe only channel with no URL at all.

The webhook payload

Our own JSON, versioned from the first release so it can be changed without breaking what you built on it. The whole batch goes in one request.

{
  "version": 1,
  "kind": "fired",
  "sent_at": "2026-11-06T22:41:00+00:00",
  "alerts": [
    {
      "rule": "disk.full",
      "severity": "critical",
      "summary": "/var on nas is 97.0% full",
      "host": "nas",
      "fingerprint": "9f2c…",
      "started_at": "2026-11-06T22:36:00+00:00",
      "resolved_at": null,
      "context": {"used_percent": 97, "mountpoint": "/var"}
    }
  ]
}

It is signed

If you set a signing key, every request carries X-SilentFailure-Signature: sha256=… over the timestamp and the raw body, and X-SilentFailure-Timestamp. Without it you cannot tell our alert from one somebody else sent to your endpoint — and an alert endpoint anyone can fire is a way to hide the real alert in noise.

Resolved is a new message

Most receivers cannot edit a message they already got, so "resolved" arrives as its own request with kind: "resolved". It is only sent if the "fired" one was.

Retries come from your group

Attempts and backoff are the notification group's own. A gateway that is down for a moment must not cost the alert.

Where we will connect, and where we will not

A webhook URL is the first field in the product that decides where the central makes an outbound connection. It is fenced, and the fence is worth knowing about before you point it somewhere.

RULEWHY
https onlyAn alert over plain http can be read and changed in transit — and it carries a signature meant to prove the message is ours.
The name is resolved, and every address is checkedReading the string is not enough: a public-looking name can point at 10.0.0.5, and it resolves again on the next call. An A record with two answers, one of them private, is still a way in.
No redirectsA 302 would otherwise be the way around everything above.
Private addresses are refused by defaultOn a self-hosted central you can allow them with ALERT_WEBHOOK_ALLOW_PRIVATE, because you own that network. Loopback and the cloud metadata address stay refused either way.

The one that is easy to get wrong

Do not route alerts through what you monitor

A Gotify in a container on the host that just died is down exactly when the alert matters, and Home Assistant on the same NAS is the same problem with a nicer interface. Keep at least one channel that does not depend on the machines being watched.

Start freeRead the install docs