Alerts (Slack, Discord, email)
Alerts send what matters about your organization to the places your team already watches: Slack, Discord, Microsoft Teams, Telegram, email or any webhook. You connect a destination once, then choose which topics go to it. Open Alerts in the dashboard to set it up.
Alerts are configured in the dashboard by the organization owner. Other members can see the setup but not change it. They are not part of the API, so API keys and the MCP server do not manage them.
How it works
- Add a destination. A destination is one place to deliver to, such as one Slack channel. Add one destination per channel.
- Route topics. For each topic, pick the destinations that should receive it and the lowest severity to send.
- Send a test. Each destination has a Send test button. The destination card shows whether its last delivery worked.
Topics are independent of the destination, so they work the same on every platform. One destination can receive several topics, and one topic can go to several destinations. To keep errors and daily summaries apart in Slack, create two destinations (two channels) and route each topic to its own.
Topics
| Topic | Sent when | Setting | Repeats |
|---|---|---|---|
| Errors | A crawl, batch or scheduled run finishes with no successful page. Robots refusals and cancellations are not sent. | none | At most once per 10 minutes for the same site and reason |
| Site down | A scheduled check of a monitored site fails. | none | At most once per hour for each schedule |
| Page changed | A monitored site changes in a way that matters. The first run, which sets the baseline, is not sent. | none | Once per detected change |
| Usage limit | Pages, searches or browser minutes reach a share of the monthly plan limit. | Alert at 50 to 100 percent (default 80). Reaching 100 percent is critical. | Once per month for each counter and level |
| Daily summary | Once a day: crawls and failures in the last 24 hours, and pages, searches and browser minutes this month against your plan. | Hour of the day in UTC, 0 to 23 (default 8) | Once a day |
Each topic carries a severity: info, warning or critical. Errors are warnings, a site that is down is critical, page changes are info, and a usage alert is a warning (critical at 100 percent). A topic's Send from severity setting hides anything below it. The daily summary is info, or a warning when something failed.
The messages name the site's host and the reason, never page content, full URLs or query strings.
Destinations
| Type | You provide | Notes |
|---|---|---|
| Slack | An Incoming Webhook URL (https://hooks.slack.com/services/...) | In Slack, create an app, turn on Incoming Webhooks and add one for the channel. A webhook posts to one channel. |
| Discord | A webhook URL (https://discord.com/api/webhooks/...) | Channel settings, Integrations, Webhooks, New Webhook. Mentions are disabled in messages. |
| Microsoft Teams | A Workflows or Incoming Webhook URL | Messages are sent as an Adaptive Card. |
| Telegram | A bot token and a chat ID or @channel | Create the bot with @BotFather and add it to the chat or channel first. |
| The address of a member of the organization | Email can only go to people in your organization. It is not offered when the deployment has no mail server. | |
| Webhook | An https URL and an optional signing secret | Sends a JSON event, described below. |
Webhook URLs for Slack, Discord and Teams are checked against the provider's own addresses, so a URL that points elsewhere is rejected. Generic webhooks must be public https URLs: addresses on private networks are refused, and redirects are not followed. Destination secrets are encrypted at rest and are never shown again after you save them; the dashboard shows only a masked label. To change a secret, create a new destination and delete the old one.
An organization can have up to 20 destinations and 50 routing rules.
Webhook events
A webhook destination receives one POST with Content-Type: application/json and the user agent XDive-Alerts/1:
{
"source": "xdive",
"topic": "site_down",
"severity": "critical",
"title": "docs.example.com is unreachable",
"message": "The scheduled check could not fetch the site.",
"fields": { "Organization": "Acme", "Site": "docs.example.com", "Reason": "fetch_failed", "Crawl": "crl_9d15" },
"link": "https://xdive.dev/dashboard",
"time": "2026-10-30T08:00:00Z"
}topic is one of errors, site_down, page_changed, usage_limit or daily_digest (the daily summary). fields varies by topic. Reply with any 2xx status; anything else is shown on the destination as a failed delivery, and the event is not retried.
Verify the signature
If you set a signing secret, every request carries X-XDive-Signature: sha256=<hex>, an HMAC-SHA256 of the raw request body with your secret. Verify it before trusting the event:
import hmac, hashlib
def valid(secret: str, body: bytes, header: str) -> bool:
expected = "sha256=" + hmac.new(secret.encode(), body, hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, header)import { createHmac, timingSafeEqual } from "node:crypto";
export function valid(secret: string, body: Buffer, header: string): boolean {
const expected = "sha256=" + createHmac("sha256", secret).update(body).digest("hex");
const a = Buffer.from(expected), b = Buffer.from(header);
return a.length === b.length && timingSafeEqual(a, b);
}Delivery and limits
- Each alert is sent once to each chosen destination, in parallel, with a 10-second timeout. A failed delivery is not retried; the destination card shows Last delivery failed with the provider's status.
- Repeated alerts are suppressed using the repeat intervals in the topics table, so a site that stays down does not flood a channel.
- A disabled destination, or a topic with no destination, sends nothing.
- Send test is limited to one every 10 seconds for each destination.
- Crawl-based alerts and the periodic checks run in the worker. A deployment that runs no worker sends no alerts.
Self-hosting
Email destinations use the deployment's SMTP settings (SMTP_HOST, SMTP_PORT, SMTP_USER, SMTP_PASSWORD, SMTP_FROM). Links in alerts use APP_URL. Alerts for the people who run the platform, such as a failing dependency, are separate: configure them in the admin settings under Global Settings. See Self-hosting.
Troubleshooting
| You see | Likely cause |
|---|---|
| "use an official Slack incoming webhook URL" | The URL is not on hooks.slack.com. Copy it from the app's Incoming Webhooks page. |
| "email alerts can only go to members of this organization" | Invite the person to the organization first, or use a Slack or webhook destination. |
| Last delivery failed, HTTP 403 or 404 | The webhook was revoked or deleted at the provider. Create a new one and replace the destination. |
| Last delivery failed, delivery request failed | The provider could not be reached, or the address is private. Check the URL and try Send test. |
| Nothing arrives and the test works | The topic has no destination, its severity is set too high, or the same alert was sent within its repeat interval. |