---
title: "Notification channels"
description: "Set up where alert notifications go, by email, Slack, Microsoft Teams, Google Chat, PagerDuty, or a signed webhook, and test each channel."
url: "https://support.outpostplatform.com/service-desk/notification-channels/"
product: "depot"
type: "how-to"
status: "draft"
ai_summary: "Alerts > Notification channels in the Outpost console. Channel kinds Email, Webhook (JSON body, optional HMAC-SHA256 signature in X-Outpost-Signature, extra headers), Slack, Microsoft Teams, Google Chat (incoming webhook URL), and PagerDuty (Events API v2 routing key). Messages per hour caps each channel. Secrets are write-only. Test sends a message and shows the result."
availability:
  plans: ["home-lab", "essentials", "enterprise", "msp"]
  permission: "alert:manage"
  preview: false
source: "https://gitlab.com/outpostplatform/docs/-/edit/main/src/content/docs/service-desk/notification-channels.md"
license: "CC BY 4.0"
---

# Notification channels

A notification channel is a destination for alert notifications, such as an
email list, a Slack channel, or a PagerDuty service.
[Alert rules](/service-desk/alert-rules/) decide which alerts go to which
channels. This page shows how to add each kind of channel and test it, so you
know notifications arrive before you need them.

## Before you begin

- You need `alert:manage`. Every channel page needs it, including reading the
  list, because a channel's settings are credentials. See
  [Roles and permissions](/depot/roles-and-permissions/).
- For an email channel, outgoing email must be set up. See
  [Configure outgoing email](/depot/email/).
- For Slack, Microsoft Teams, or Google Chat, create an incoming webhook in
  that service first. For PagerDuty, create a service integration that uses the
  Events API v2 and copy its routing key.

## Channel kinds

| Kind | What you enter | Notes |
| --- | --- | --- |
| **Email** | One or more recipient addresses | Sent through the outgoing email provider in **Settings** > **Email**. Everyone listed gets the same message. |
| **Webhook** | **URL**, **Signing secret (optional)**, and **Extra headers (optional)** | Posts a JSON body. See [Receive webhooks](#receive-webhooks). |
| **Slack** | **Incoming webhook URL** | Posts to the Slack channel the webhook belongs to. |
| **Microsoft Teams** | **Incoming webhook URL** | Posts to the Teams channel the webhook belongs to. |
| **Google Chat** | **Incoming webhook URL** | Posts to the Google Chat space the webhook belongs to. |
| **PagerDuty** | **Integration routing key** | Triggers a PagerDuty incident. When the rule also sends on clear, the same alert resolves it. |

Webhook URLs, signing secrets, headers, and routing keys are stored
write-only. The console shows that one is saved but never shows it back. To
keep a saved secret when you edit a channel, leave its box empty.

## Add a channel

1. Select **Alerts** > **Notification channels**, then **New channel**. On the
   MSP plan, open the client first.
2. In **Name**, enter a name your team will recognize in a rule, such as
   "On-call phone".
3. In **Kind**, choose the kind of channel.
4. Under **Where it goes**, enter the details for that kind:
   - **Email**: type an address in **Add a recipient** and select **Add**.
     Repeat for each recipient.
   - **Webhook**: enter the **URL**. To let the receiver check that a request
     came from your Outpost, enter a **Signing secret (optional)**. To send headers the
     receiver needs, such as an authorization header, select **Add header**.
   - **Slack**, **Microsoft Teams**, or **Google Chat**: paste the **Incoming
     webhook URL**.
   - **PagerDuty**: paste the **Integration routing key**.
5. In **Messages per hour**, enter the most messages this channel may send in
   an hour, or `0` for no limit. Messages beyond the limit are held until the
   next hour, not dropped.
6. Leave **Enabled** selected.
7. Select **Save channel**.

## Test a channel

1. In the channel list, select **Test** on the channel.
2. Check the **Last result** column. It shows **Test message sent.** or
   **Test failed.** with the reason.
3. Check that the message arrived where you expected it.

Test every channel after you create or change it. A wrong address or URL looks
the same as a quiet week until the day nobody is told.

## Receive webhooks {#receive-webhooks}

A webhook channel sends an HTTP `POST` with a JSON body, the header
`Content-Type: application/json`, and the header `User-Agent: Outpost-Depot`.

```json
{
  "alert_public_id": "<alert-id>",
  "purpose": "notify",
  "tier": 0,
  "severity": "critical",
  "category": "disk",
  "title": "<alert-title>",
  "detail": "<alert-detail>",
  "hostname": "<endpoint-hostname>",
  "client_name": "<client-name>",
  "raised_at": "2026-10-12T03:12:00Z",
  "console_url": "<link-to-the-alert>"
}
```

| Field | Meaning |
| --- | --- |
| `alert_public_id` | The alert's ID. It is the same for every message about one alert. |
| `purpose` | `notify` for the first message, `escalation` for an escalation step, or `resolve` when the condition cleared. |
| `tier` | `0` for the first message, and the step number for an escalation. |
| `severity`, `category`, `title`, `detail` | The alert. `detail` is left out when the alert has none. |
| `hostname` | The endpoint, left out for an alert that belongs to no endpoint. |
| `client_name` | The client the alert belongs to. |
| `raised_at` | When the condition first fired, in UTC. |
| `console_url` | A link to the alert in the console, when one can be built. |

When the channel has a signing secret, the request carries the header
`X-Outpost-Signature`. Its value is the HMAC-SHA256 of the raw request body,
keyed with the signing secret and written as lowercase hexadecimal. Compute the
same value on your side and reject a request whose signature does not match.

## Turn a channel off or delete it

- To stop a channel sending without deleting it, select **Edit**, clear
  **Enabled**, and select **Save channel**. The list shows it as **Disabled**,
  and the **Switched off** view lists every disabled channel.
- Select **Delete** and confirm to remove a channel. Rules that use it stop
  notifying anybody through it.

## If something goes wrong

| Symptom | Cause | Fix |
| --- | --- | --- |
| **Test failed.** on an email channel | Outgoing email is not set up, or the provider refused the message. | Check [Configure outgoing email](/depot/email/) and send a test from there. |
| **Test failed.** on a Slack, Teams, or Google Chat channel | The incoming webhook was deleted or the URL is wrong. | Create a webhook in that service and paste the URL again. |
| Test messages arrive, but alerts do not | No enabled rule sends to this channel for that alert. | Check the alert's **Who was told** card and your [alert rules](/service-desk/alert-rules/). |

## Next steps

- [Create alert rules](/service-desk/alert-rules/)
- [Alerts](/service-desk/alerts/)
