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 dns and status events for your own domains to a team chat channel, so an unexpected change gets noticed in minutes, not days.
  • Open a ticket when a whois event shows a customer's or partner's domain nearing expiry.
  • Feed tech events for competitors' domains into your CRM to see who just switched providers.
  • Watch lookalike domains of your brand and alert when one starts resolving.