> ## Documentation Index
> Fetch the complete documentation index at: https://docs.overwatchapp.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Email and webhook alert channels: setup and configuration

> Send Overwatch monitor alerts to an email address or any HTTP endpoint — including how to verify webhook requests with an HMAC secret.

Email and webhook channels give you two direct delivery options. Email sends a notification to any address when a monitor changes state. Webhook delivers an HTTP POST to an endpoint you control, letting you integrate Overwatch alerts with any system — a custom Slack bot, an incident management tool, a database, or your own application logic.

## Email channel

Create an email alert channel by passing `type: "EMAIL"` and a `config` object with the recipient address.

```bash theme={null}
curl -X POST https://overwatchapp.dev/api/v1/alerts \
  -H "Authorization: Bearer ow_live_sk_<secret>" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "On-call email",
    "type": "EMAIL",
    "config": {
      "to": "oncall@example.com"
    }
  }'
```

### Config fields

<ParamField body="config.to" type="string" required>
  The recipient email address. Overwatch sends one email per status-change event for each monitor bound to this channel.
</ParamField>

<Note>
  Email delivery relies on Overwatch's sending infrastructure. If you do not receive an alert, check your spam folder and make sure `alerts@mail.overwatchapp.dev` is allowed by your mail filters.
</Note>

***

## Webhook channel

Create a webhook alert channel by passing `type: "WEBHOOK"` and a `config` object with your endpoint URL. You can also include an optional HMAC secret so you can verify that requests genuinely come from Overwatch.

```bash theme={null}
curl -X POST https://overwatchapp.dev/api/v1/alerts \
  -H "Authorization: Bearer ow_live_sk_<secret>" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Incident webhook",
    "type": "WEBHOOK",
    "config": {
      "url": "https://your-server.com/hooks/overwatch",
      "secret": "a-random-string-you-choose"
    }
  }'
```

### Config fields

<ParamField body="config.url" type="string" required>
  The HTTPS endpoint that Overwatch sends a `POST` request to when a monitor changes state. Must be publicly reachable.
</ParamField>

<ParamField body="config.secret" type="string">
  An optional HMAC secret. When set, Overwatch signs each outgoing request so you can verify authenticity on your server. See [Verifying webhook requests](#verifying-webhook-requests) below.
</ParamField>

### Webhook payload

When a monitor changes state, Overwatch sends a `POST` request with a `Content-Type: application/json` body. The payload includes the details of the status-change event:

* **Monitor identifiers** — the monitor's `id` and `name`.
* **Monitor type** — the check type, such as `HTTP`, `TCP`, `TLS`, `DNS`, or `SCHEDULED`.
* **Status transition** — the previous status and the new status (e.g. `up` → `down`).
* **Timestamp** — when the status change occurred.

The exact field names in the payload are subject to change as the webhook schema stabilizes. Check the [API reference](/api-reference/alerts) for the canonical payload definition.

### Verifying webhook requests

When you set a `secret` in the config, Overwatch includes a signature header with each request. On your server, compute an HMAC of the raw request body using the same secret and compare it to the header value. Reject any request where the signatures do not match.

```javascript theme={null}
const crypto = require('crypto');

function verifySignature(rawBody, secret, signatureHeader) {
  const expected = crypto
    .createHmac('sha256', secret)
    .update(rawBody)
    .digest('hex');
  return crypto.timingSafeEqual(
    Buffer.from(expected),
    Buffer.from(signatureHeader)
  );
}
```

<Warning>
  Always use a constant-time comparison (such as `crypto.timingSafeEqual`) when checking signatures. Standard string equality is vulnerable to timing attacks.
</Warning>

***

## Updating a channel's config

Use `PATCH /api/v1/alerts/:id` to update an existing channel's name, config, or `enabled` state. You can pass any combination of fields — only the fields you include are changed.

```bash theme={null}
# Update the recipient email address
curl -X PATCH https://overwatchapp.dev/api/v1/alerts/<channel-id> \
  -H "Authorization: Bearer ow_live_sk_<secret>" \
  -H "Content-Type: application/json" \
  -d '{
    "config": {
      "to": "new-oncall@example.com"
    }
  }'
```

```bash theme={null}
# Rotate the webhook secret
curl -X PATCH https://overwatchapp.dev/api/v1/alerts/<channel-id> \
  -H "Authorization: Bearer ow_live_sk_<secret>" \
  -H "Content-Type: application/json" \
  -d '{
    "config": {
      "url": "https://your-server.com/hooks/overwatch",
      "secret": "new-rotated-secret"
    }
  }'
```

<Note>
  When you update `config`, pass the full config object. Overwatch replaces the stored config entirely rather than merging individual keys.
</Note>

## Deleting a channel

```bash theme={null}
curl -X DELETE https://overwatchapp.dev/api/v1/alerts/<channel-id> \
  -H "Authorization: Bearer ow_live_sk_<secret>"
```

A successful response returns `200` with the ID of the deleted channel:

```json theme={null}
{
  "data": { "id": "3b6e1f2a-..." }
}
```

Deleting a channel removes all its monitor bindings. Any monitor that used this channel as its only alert destination will no longer send notifications until you bind it to a new channel.

<Warning>
  Deletion is permanent and cannot be undone. Verify that no production monitors depend exclusively on this channel before you delete it.
</Warning>
