Watch domains and get every change as a webhook
Watch domains, receive their DNS, WHOIS, availability and technology changes as signed webhook deliveries, and verify the signature in a few lines.
Looking up a domain tells you its past. Watching it tells you its future: every change from now on becomes an event, in DigStory and, if you want, delivered to your own systems.
Start watching
Open Watching, type a domain and press Watch. You can also hit Watch on any domain page. Watched domains belong to your team, so everyone on it sees the same list and the same events. The free plan includes 25 watched domains, Pro 1,000 and Business 10,000.
What counts as a change
Every event has a kind:
| Kind | Example | Data |
|---|---|---|
dns |
An MX record was added | type, value, change (added or removed) |
whois |
The expiry date moved | field, old, new |
status |
The domain stopped resolving | event (gone or back) |
tech |
A CDN was adopted | technology, change |
The Events panel lists them newest first, and the API serves the same list at GET /api/v1/watching/events.
Send them to a webhook
Team owners and admins can set a webhook URL and a signing secret in the Webhook panel. DigStory then POSTs new events to that URL as JSON, in batches:
{
"team": {"id": 7, "name": "Acme security"},
"events": [
{
"id": 98121,
"kind": "dns",
"domain": "example.com",
"domain_id": 4512,
"at": "2026-11-02T08:14:00Z",
"data": {"family": "name", "type": "mx", "value": "mail.example.net", "change": "added"}
}
]
}
Events that fail to deliver are kept and retried, and you can trigger a delivery by hand from the panel at any time.
Verify the signature
When a secret is set, every delivery carries an x-digstory-signature header: sha256= followed by the hex HMAC-SHA256 of the raw request body under your secret. Compute the same value and compare before you trust the payload.
Node.js
import crypto from "node:crypto";
function verify(rawBody, header, secret) {
const expected =
"sha256=" + crypto.createHmac("sha256", secret).update(rawBody).digest("hex");
return header.length === expected.length &&
crypto.timingSafeEqual(Buffer.from(header), Buffer.from(expected));
}
Python
import hashlib, hmac
def verify(raw_body: bytes, header: str, secret: str) -> bool:
expected = "sha256=" + hmac.new(secret.encode(), raw_body, hashlib.sha256).hexdigest()
return hmac.compare_digest(header, expected)
Always sign over the raw body, before any JSON parsing, and use a constant-time comparison.
Ideas for what to do with them
- Post
dnsandstatusevents for your own domains to a team chat channel, so an unexpected change gets noticed in minutes, not days. - Open a ticket when a
whoisevent shows a customer's or partner's domain nearing expiry. - Feed
techevents for competitors' domains into your CRM to see who just switched providers. - Watch lookalike domains of your brand and alert when one starts resolving.