Notification channels
A channel is a destination for alerts. Add as many as you need, then attach them to individual monitors (or to all monitors by default).
Channels vs. monitor overrides
Channels are defined at the organisation level. Each channel can be marked as the default — meaning new monitors send to it automatically. On any given monitor you can override the default and pick a custom subset.
Slack
- In Slack, go to
Apps → Incoming Webhooks → Add to Slackand select the channel that should receive alerts. - Copy the webhook URL Slack gives you.
- In Page Deltas, open the
Channelspage,Add a channel, pickSlack, paste the URL, and save. - Click
Send testto confirm the message lands in the right Slack channel.
Discord
In your Discord server, open Server Settings → Integrations → Webhooks → New Webhook. Copy the URL and paste it into a new Discord channel in Page Deltas.
Microsoft Teams
In Teams, right-click the target channel, Connectors → Incoming Webhook → Configure. Name it Page Deltas, save, and copy the URL into Page Deltas.
Add the recipient address. We send a verification email to that address first — the channel stays in a pending verification state and won't receive alerts until the recipient confirms. Outbound mail is sent from a verified domain we control. For team distribution, use a group alias rather than adding individual addresses one by one.
Generic webhook
Use this when you want to drive your own system from alerts (Linear, Jira, a Lambda, a Slack-but-via-bot, etc.).
Payload
The body is a flat JSON object. New fields may be added over time, so ignore unknown keys rather than rejecting them.
POST <your URL>
Content-Type: application/json
X-Signature: sha256=<hex>
{
"event": "change.detected",
"monitor_id": "...",
"monitor_url": "https://example.com/pricing",
"monitor_name": "Competitor pricing page",
"change_id": "...",
"detected_at": "2026-06-01T12:00:00Z",
"summary": "Pro plan increased from $29 to $39/month.",
"before_screenshot_url": "https://.../before.png",
"after_screenshot_url": "https://.../after.png",
"dashboard_url": "https://app.pagedeltas.com/monitors/..."
}Signature verification (HMAC)
Each request carries an X-Signature header of the form sha256=<hex>, where the value is the HMAC-SHA256 of the raw request body using your channel's secret — shown once at creation time. There is no timestamp component.
# Node.js example
import crypto from "node:crypto";
function verify(req, rawBody, secret) {
const header = req.headers["x-signature"]; // "sha256=<hex>"
const expected =
"sha256=" +
crypto.createHmac("sha256", secret).update(rawBody).digest("hex");
return crypto.timingSafeEqual(
Buffer.from(header),
Buffer.from(expected),
);
}Delivery and failures
| Behaviour | Detail |
|---|---|
| Attempts | Each alert is delivered with a single attempt per channel. There are currently no automatic retries — make your receiver respond quickly and accept duplicates defensively. |
| Failures | A non-2xx response or network error marks that delivery failed. The monitor itself is not paused for delivery failures. |
| Audit | Every attempt (success or failure, with HTTP status) is recorded server-side in the delivery-attempts log. |
Best practices
- Use one channel per Slack workspace channel — don't reuse a webhook for multiple Slack rooms.
- For high-volume monitors, send to a dedicated Slack channel rather than a busy #general.
- For mission-critical alerts, attach two channels of different types (e.g., Slack + email) so a Slack outage doesn't hide a change.