Setting up alert channels
Alert channels are the destinations CompleteStatus can notify when a monitor goes down or recovers. Channels belong to a project, and every monitor in that project can route its events to one or more of them through per-monitor alert rules.
CompleteStatus supports twenty-one channel types. Fifteen are available on every plan, including Free; the PagerDuty/Opsgenie pager integrations and the GitHub/GitLab/Jira/Linear ticketing integrations are available on Pro and up:
| Type | What you need | Plans |
|---|---|---|
| A recipient email address | All | |
| Slack | An incoming-webhook URL (https://hooks.slack.com/services/…) |
All |
| Microsoft Teams | A Power Automate workflow URL that posts to a Teams channel | All |
| Discord | A channel webhook URL | All |
| Telegram | A bot token and a chat ID | All |
| Google Chat | A space's incoming-webhook URL (https://chat.googleapis.com/v1/spaces/…) |
All |
| Mattermost | An incoming-webhook URL from your Mattermost server | All |
| Rocket.Chat | An incoming-webhook URL from your Rocket.Chat workspace | All |
| Zulip | Your server URL, a bot's email + API key, and a stream | All |
| Webex | An incoming-webhook URL (https://webexapis.com/v1/webhooks/incoming/…) |
All |
| Matrix | A homeserver URL, a room ID and a bot user's access token | All |
| Webhook | Any HTTPS endpoint you control, plus an optional signing secret | All |
| PagerDuty | An Events API v2 integration key (routing key) | Pro+ |
| Opsgenie | An API-integration key, plus your account region (US/EU) | Pro+ |
| ntfy | A topic name — and optionally your self-hosted server URL | All |
| Pushover | An application API token and your user key | All |
| Gotify | Your Gotify server URL and an application token | All |
| GitHub Issues | An owner/repo and an access token with Issues write |
Pro+ |
| GitLab Issues | A project ID and access token — self-managed instances supported | Pro+ |
| Jira | Your Jira Cloud URL, account email + API token, and a project key | Pro+ |
| Linear | An API key and a team ID | Pro+ |
Looking for Zapier, Make or n8n? Those connect through the REST-hook automation API, not an alert channel.
Adding a channel
- Go to /settings/channels and pick the project from the project switcher at the top of the page.
- Click to add a channel, then choose a Type.
- Give it a Name (for example "On-call Slack") — this is how the channel appears in monitor alert rules and in test-send confirmations.
- Fill in the type-specific fields:
- Email — the destination Email address (e.g.
alerts@example.com). - Slack / Discord — the Webhook URL from your Slack app or Discord channel integration settings.
- Microsoft Teams — the Webhook URL of your Power Automate workflow (see Microsoft Teams below).
- Telegram — the Bot token issued by @BotFather and the Chat ID of the group or user the bot should message (group IDs look like
-1001234567890). - Webhook — the destination URL and an optional Signing secret (strongly recommended; see below).
- PagerDuty — the Events API v2 Integration key (see PagerDuty below).
- Opsgenie — the API key and your account Region (see Opsgenie below).
- ntfy — the Topic and, for self-hosted servers, the Server URL (see ntfy below).
- Pushover — the application API token and your User key (see Pushover below).
- Google Chat / Mattermost / Rocket.Chat / Webex — the Webhook URL from the space/channel integration (see the chat channels below).
- Zulip — the Server URL, the bot's Email and API key, and the Stream to post to.
- Matrix — the Homeserver URL, the internal Room ID (starts with
!) and a bot user's Access token. - Gotify — your Server URL and an application Token (see Gotify below).
- GitHub / GitLab / Jira / Linear — repository/project coordinates plus an API token (see Ticketing integrations below).
- Email — the destination Email address (e.g.
- Leave Enabled switched on and click Save channel.
Note: Secrets are never shown again after saving. When you edit a channel, the webhook URL, tokens, integration keys and signing secret fields are blank — leave them blank to keep the stored value, or type a new one to replace it.
Microsoft Teams
Microsoft retired the classic Office 365 connector webhooks, so Teams alerts are delivered through a Power Automate workflow that receives a webhook and posts an Adaptive Card into your channel:
- In Teams, open the channel you want alerts in, click ⋯ → Workflows, and pick the template "Post to a channel when a webhook request is received" (or build the same flow at make.powerautomate.com with the "When a Teams webhook request is received" trigger followed by "Post card in a chat or channel").
- Choose the team and channel, then create the workflow.
- Copy the workflow's HTTP POST URL (shown when the workflow is created, and later under the flow's "When a Teams webhook request is received" trigger).
- Paste it into the channel's Webhook URL field in CompleteStatus.
CompleteStatus posts an Adaptive Card with the status colour (red for down, green for recovery), the monitor, the error, the incident duration on recovery, and a View incident button.
PagerDuty
Available on Pro and up. CompleteStatus uses the PagerDuty Events API v2: a down event triggers a PagerDuty incident and the recovery automatically resolves it (the deduplication key is derived from the CompleteStatus incident, so retries and flapping never open duplicates).
- In PagerDuty, open Services → Service Directory and pick (or create) the service that should receive alerts.
- On the service's Integrations tab, click Add an integration and choose Events API V2.
- Copy the 32-character Integration Key.
- In CompleteStatus, create a channel of type PagerDuty and paste the key into Integration key (routing key).
Severity is sent as critical for down events (PagerDuty routes and escalates from there). Route only down and up events to a PagerDuty channel — that gives you trigger + auto-resolve without noise.
Opsgenie
Available on Pro and up. CompleteStatus uses the Opsgenie Alerts API: a down event creates an alert (with an alias derived from the incident, so retries dedup into one alert) and the recovery closes it.
- In Opsgenie (or Jira Service Management Operations), go to Teams, pick your team, and open Integrations → Add integration.
- Choose the API integration type and give it a name.
- Copy the generated API key and make sure the integration is enabled with create and update access.
- In CompleteStatus, create a channel of type Opsgenie, paste the API key, and pick your Region — EU if you log in at
app.eu.opsgenie.com, otherwise US.
Down alerts are created with priority P1; the alert's details include the monitor and a link to the CompleteStatus incident.
ntfy
ntfy delivers push notifications to your phone or desktop with no account required:
- Install the ntfy app (Android/iOS) or open ntfy.sh in a browser.
- Subscribe to a topic of your choosing. Topics are not access-controlled on the public server — pick something hard to guess, e.g.
acme-alerts-x8k2p. - In CompleteStatus, create a channel of type ntfy and enter the same Topic. Leave Server blank to use
https://ntfy.sh, or enter your self-hosted server URL.
Down alerts are published with urgent priority and a 🚨 tag; recoveries with default priority and a ✅ tag. Tapping the notification opens the incident.
Warning: Like webhooks, a self-hosted ntfy server must be publicly reachable — private and internal addresses are refused.
Pushover
Pushover sends push notifications to your devices for a one-time device purchase:
- Log in at pushover.net — your User Key is shown top-right on the dashboard.
- Scroll to Your Applications and click Create an Application/API Token. Name it (e.g. "CompleteStatus") and copy the API Token.
- In CompleteStatus, create a channel of type Pushover and enter the API token and User key (a group key works too).
- Optionally tick Emergency priority for down alerts — down notifications then repeat every 60 seconds for up to an hour until someone acknowledges them — and set a notification Sound (e.g.
siren).
Without emergency priority, down alerts are sent as high priority (bypasses quiet hours) and recoveries as normal priority.
Google Chat, Mattermost, Rocket.Chat, Webex, Zulip and Matrix
Six more chat platforms, all included on every plan.
Google Chat
- In Google Chat, open the space, click the space name → Apps & integrations → Webhooks (a Google Workspace account is required — webhooks are not available on personal accounts).
- Add webhook, name it (e.g. "CompleteStatus") and copy the URL — it starts with
https://chat.googleapis.com/v1/spaces/…. - In CompleteStatus, create a channel of type Google Chat and paste the URL.
Alerts arrive as a card: status dot (🔴 down / 🟢 recovered) in the header, the monitor, target and error, and a View incident button.
Mattermost
- In Mattermost, open Main menu → Integrations → Incoming Webhooks → Add Incoming Webhook (a system admin may need to enable integrations first).
- Pick the target channel, save, and copy the webhook URL.
- In CompleteStatus, create a channel of type Mattermost and paste the URL.
Messages use the familiar Slack shape — red attachment for down, green for recovery. Self-hosted servers must be publicly reachable.
Rocket.Chat
- In Rocket.Chat, go to Administration → Workspace → Integrations → New → Incoming.
- Enable it, choose the channel to post to, save, and copy the Webhook URL.
- In CompleteStatus, create a channel of type Rocket.Chat and paste the URL.
Down alerts are red, recoveries green, and the attachment title links to the incident. Self-hosted servers must be publicly reachable.
Webex
- In Webex, add the Incoming Webhooks app to your space (apphub.webex.com → Incoming Webhooks), name it and pick the space.
- Copy the webhook URL — it starts with
https://webexapis.com/v1/webhooks/incoming/…. - In CompleteStatus, create a channel of type Webex and paste the URL.
Alerts arrive as a markdown message with the status emoji, the details, and a View incident link.
Zulip
- In Zulip, create a bot: Personal settings → Bots → Add a new bot (a Generic bot is fine). Note its email and API key from the bot card.
- Subscribe the bot to the stream you want alerts in.
- In CompleteStatus, create a channel of type Zulip with your Server URL (e.g.
https://yourorg.zulipchat.com), the bot's email and API key, and the Stream name.
Every alert is posted under a topic named after the monitor, so a monitor's down and recovery thread into one conversation. Self-hosted servers must be publicly reachable.
Matrix
- Create (or pick) a Matrix user to act as the bot and invite it to the target room. Using your personal account's token works but a dedicated bot user is strongly recommended.
- Get the user's access token (in Element: Settings → Help & About → Access Token).
- Get the room's internal Room ID — it starts with
!(in Element: Room settings → Advanced). A#aliaswill not work. - In CompleteStatus, create a channel of type Matrix with the Homeserver URL (e.g.
https://matrix.org), the Room ID and the Access token.
Messages are sent with an HTML body (colour-coded title, incident link) plus a plain-text fallback. Deliveries use a transaction ID derived from the incident, so a retried send can never duplicate a message in the room. Self-hosted homeservers must be publicly reachable.
Gotify
Gotify is a self-hosted push-notification server with Android and browser clients:
- On your Gotify server's web UI, open Apps → Create Application (e.g. "CompleteStatus") and copy the application token.
- In CompleteStatus, create a channel of type Gotify with your Server URL and the Application token.
Down alerts are sent at priority 8 (intrusive — pops over Do-Not-Disturb in the Android app), recoveries at priority 2. Tapping the notification opens the incident. Like all self-hosted destinations, the server must be publicly reachable.
Ticketing integrations (GitHub, GitLab, Jira, Linear)
Available on Pro and up. Ticketing channels file a ticket when an incident opens and follow up on the same ticket when the monitor recovers — an auditable paper trail per incident, driven by the same alert rules as every other channel. Route only down and up events to a ticketing channel.
The created ticket's identifier is remembered per incident, so retries never file duplicates and the recovery always lands on the right ticket.
GitHub Issues
Opens an issue (labelled completestatus, incident) on down; comments and closes it on recovery.
- Create a token: GitHub → Settings → Developer settings. Either a classic PAT with the repo scope, or a fine-grained token with Issues: Read and write on the target repository.
- In CompleteStatus, create a channel of type GitHub Issues with the Repository in
owner/repoform and the Access token.
GitLab Issues
Opens an issue on down; adds a note and closes it on recovery. Works with gitlab.com and self-managed instances (the instance must be publicly reachable).
- Create a Project access token with the api scope (Project → Settings → Access tokens), or use a personal access token with api scope.
- Find the numeric Project ID on the project's overview page (⋯ menu → Copy project ID).
- In CompleteStatus, create a channel of type GitLab Issues with the Server URL (leave blank for gitlab.com), the Project ID and the Access token.
Jira
Creates an issue (default type Task) in your project on down. On recovery it always adds a comment; if you configure a Done transition ID it also moves the issue to Done — workflows differ per project, so the transition is opt-in.
- Create an API token at id.atlassian.com/manage-profile/security/api-tokens.
- In CompleteStatus, create a channel of type Jira with your Jira Cloud URL (
https://yourorg.atlassian.net), your account email, the API token, the Project key (e.g.OPS) and optionally an Issue type (defaults to Task). - Optional: to auto-close on recovery, find the Done transition's numeric ID (Project settings → Workflows, or
GET /rest/api/3/issue/{key}/transitions) and enter it as the Done transition ID.
Linear
Creates an issue in your team on down and moves it to the team's Done state on recovery (the completed state is looked up once and cached).
- Create an API key: Linear → Settings → Security & access → API keys.
- Copy the Team ID from the team's settings page (Settings → Teams → your team; the ID is a UUID).
- In CompleteStatus, create a channel of type Linear with the API key and Team ID.
Testing a channel
Each channel row has a Test send button. Clicking it delivers a "CompleteStatus test alert" message to the channel:
- On success the channel is marked verified and you see "Test alert sent … Channel verified."
- On failure the delivery error is shown so you can fix the URL, token or address.
Always test a channel before relying on it for production alerts.
Note: For PagerDuty and Opsgenie, the test send creates a real (test-labelled) incident/alert in the vendor — that is the only way to prove the key works end to end. Resolve or close it there afterwards. The same applies to the ticketing integrations: a test send files a real "CompleteStatus test alert" issue in GitHub/GitLab/Jira/Linear — close it there after verifying.
Routing monitors to channels (alert rules)
Creating a channel does not by itself send anything. Notifications are driven by alert rules, configured on each monitor's detail page (open the monitor from /monitors):
- On the monitor page, add an alert rule.
- Choose the channel (only channels from the monitor's own project are offered).
- Tick the events the rule fires for:
down,up,anomaly,cert_expiry,grade_drop. At least one is required. - Set a cooldown in minutes (0–1440). While a channel has sent an alert for this monitor within the cooldown, further sends to that channel are skipped — this is the flapping protection.
- Save. Rules can be edited, toggled on/off, or deleted at any time from the same page.
down alerts fire when an incident opens (a monitor is confirmed down after two consecutive failed checks), and up alerts fire when it recovers. See /docs/incidents-and-escalation for the full incident lifecycle.
Note: A rule only delivers if both the rule and its channel are enabled. Toggling a channel off silences it across every monitor that routes to it, without deleting any configuration.
How delivery works
Alert fan-out is queued and retry-safe:
- Deliveries are deduplicated — one delivery per incident, channel and event, so a retried job never double-pings you.
- Failed sends are retried automatically with increasing backoff (10 seconds, 1 minute, 5 minutes).
- If an active maintenance window covers the monitor, the entire fan-out is suppressed (the incident is still recorded). See /docs/maintenance-windows.
Webhook payload and signature
The generic webhook channel POSTs a JSON body describing the event:
{
"event": "down",
"severity": "critical",
"title": "Monitor DOWN: API",
"message": "API (https://api.example.com) is DOWN — HTTP 500. Since …",
"timestamp": "2026-07-04T09:00:00+00:00",
"timestamp_unix": 1783242000,
"monitor": { "id": 1, "name": "API", "target": "https://api.example.com", "type": "uptime" },
"incident": { "id": 42, "cause": "HTTP 500", "opened_at": "…", "resolved_at": null, "url": "…/incidents/42" }
}
Every request carries two headers when a signing secret is set:
X-CompleteStatus-Timestamp— Unix seconds when the request was signed.X-CompleteStatus-Signature—sha256=followed by the hex HMAC-SHA256 of the exact raw request body, keyed with your secret.
To verify, recompute the HMAC over the raw body with your shared secret and compare it (constant-time) to the header value after the sha256= prefix. Reject requests with stale timestamps to defend against replays.
Warning: Every user-supplied destination URL — webhooks, chat webhooks (Slack, Discord, Teams, Google Chat, Mattermost, Rocket.Chat, Webex), self-hosted servers (ntfy, Zulip, Matrix, Gotify, GitLab) and Jira instances — must be publicly reachable. CompleteStatus validates and pins the resolved public IP and does not follow redirects, so endpoints on private or internal addresses are refused.
Plan availability
Fifteen of the twenty-one channel types — email, Slack, Microsoft Teams, Discord, Telegram, Google Chat, Mattermost, Rocket.Chat, Zulip, Webex, Matrix, webhook, ntfy, Pushover and Gotify — are included on every plan (Free, Pro, Business, Agency), as are the Zapier/Make/n8n automation hooks. The PagerDuty and Opsgenie pager integrations and the GitHub, GitLab, Jira and Linear ticketing integrations are available on Pro and up. Plan differences that otherwise affect alerting are indirect: monitor count (10 / 50 / 250 / 500) and minimum check interval (3 min / 60 s / 60 s / 60 s), which determine how quickly a failure can be detected in the first place.
Related guides
- /docs/incidents-and-escalation — when alerts fire and how to manage incidents.
- /docs/maintenance-windows — muting alerts during planned work.
- /docs/automation-hooks — trigger Zapier, Make or n8n workflows from incident events.
Further reading: Send alerts where your team actually lives and Alert fatigue — and how to undo it on the blog.