Webhooks
Configure webhooks to receive real-time HTTP callbacks whenever DMARCdrift fires an alignment regression, spoofing, or DNS change alert on your domain.
Webhooks let DMARCdrift push alert events to your own infrastructure — a Slack bot, a PagerDuty integration, a custom SIEM pipeline, or any HTTPS endpoint you control. They are available on the Pro plan.
Creating a webhook endpoint
Go to Settings → Integrations → Webhooks and click New webhook. Provide:
- URL — an HTTPS endpoint that accepts
POSTrequests. Plain HTTP and private/internal IPs are not accepted. - Domains — the domains whose alerts trigger a delivery. Leave blank to receive alerts from all domains in your account.
- Event types — the alert types that trigger a delivery. Leave blank to receive all event types.
After saving, a webhook secret is shown once. Copy it immediately — you'll use it to verify incoming payloads. The secret is never shown again.
You can have up to 10 webhook endpoints per account.
Event types
| Event type | When it fires |
|---|---|
alert.alignment_regression | SPF/DKIM alignment pass rate drops significantly day-over-day |
alert.spoofing | High volume of unauthenticated mail from senders not in your SPF record |
alert.operational_dmarc_changed | Your DMARC TXT record at _dmarc.yourdomain.com changed |
alert.operational_spf_changed | Your SPF TXT record changed |
alert.operational_dkim_changed | A DKIM selector in your reports changed |
alert.blocklist | A sending IP in your reports appeared on a major blocklist |
If you configure specific event types on an endpoint, it only receives deliveries for those types. An endpoint with no event types configured receives all of them.
The same logic applies to domains: configure specific domains to scope deliveries to those domains only, or leave blank to receive alerts from all domains in your account.
Payload format
DMARCdrift sends a POST request with Content-Type: application/json. The body:
{
"event": "alert.alignment_regression",
"fired_at": "2026-05-01T04:30:00+00:00",
"domain_id": "dddddddd-dddd-dddd-dddd-dddddddddddd",
"account_id": "acct-aaaa-aaaa-aaaa-aaaaaaaaaaaa",
"context": {
"drop_pct": 35.2,
"prev_pass_rate": 98.1,
"curr_pass_rate": 62.9
}
}The context object is alert-type specific. For operational (DNS-change) alerts it contains the old and new record values. For alignment and spoofing alerts it contains the metrics that triggered the threshold.
Verifying payloads
Every delivery includes two headers:
| Header | Value |
|---|---|
X-DMARCdrift-Signature | sha256=<hex> — HMAC-SHA256 of the raw request body, keyed with your webhook secret |
X-DMARCdrift-Delivery-ID | UUID of the delivery attempt |
Always verify the signature before processing the payload. Compute HMAC-SHA256 over the raw request body using your secret, prefix the result with sha256=, and compare it to the header using a constant-time comparison.
Example in Python:
import hashlib
import hmac
def verify_signature(secret: str, body: bytes, header: str) -> bool:
expected = "sha256=" + hmac.new(secret.encode(), body, hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, header)Example in Node.js:
const crypto = require("crypto");
function verifySignature(secret, body, header) {
const expected = "sha256=" + crypto
.createHmac("sha256", secret)
.update(body)
.digest("hex");
return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(header));
}If the signature does not match, discard the request — it did not come from DMARCdrift.
Delivery and retries
DMARCdrift attempts delivery up to 3 times with a 5-minute cadence. A delivery is considered successful if your endpoint returns a 2xx status code within 10 seconds. Any other response or a timeout is treated as a failure and the delivery is retried.
The X-DMARCdrift-Delivery-ID header is the same UUID across all retry attempts for a given event, so you can use it to deduplicate on your end.
Responding to deliveries
Return 200 OK (or any 2xx) as quickly as possible. If you need to do slow processing, accept the payload and process it asynchronously — do not block the response waiting for downstream work to complete.
Disabling and deleting endpoints
To pause deliveries without losing the configuration, use the Enabled toggle. A disabled endpoint receives no deliveries but keeps its secret and settings.
To remove an endpoint permanently, click Delete. Any in-flight deliveries to that endpoint are abandoned.
If your account downgrades from Pro, all webhook endpoints are automatically disabled.
See also: API keys — programmatic read access to your data. API reference — full endpoint documentation.