← All use cases
Compliance & RegulatoryAI

WHOIS and Domain Ownership Change Detection

Track domain registration, registrar, and nameserver changes - useful for brand protection, M&A signal, and incident response.

Verid Use Cases·4 min read

The scenario

You own a brand whose name is registered as a domain in several TLDs. When one of those domains changes hands, expires, or moves registrars, you want a heads-up - both for brand protection ("did someone just take this from us?") and for competitive intelligence ("a startup just registered this; what are they building?").

For incident response teams, the same monitor catches phishing-domain registration patterns.

The problem

WHOIS is a public protocol but lookup endpoints are inconsistent, rate-limited, and increasingly redacted (GDPR). You can pay for an enterprise domain-intelligence feed, but that's overkill if you're watching twenty domains. Building your own WHOIS poller against a free provider tends to break every six months as the providers tighten access.

How Verid solves it

Public WHOIS lookup web pages - whois.com/whois/<domain>, lookup.icann.org/<domain>, and various registrar lookup pages - render structured information about a domain. Verid's prompt extractor reads the rendered page and pulls out registrar, creation date, expiry, and nameservers as structured fields. The predicate fires when any of them change.

Build the monitor

Extraction config

{
  "method": "prompt",
  "prompt": "From this WHOIS lookup page, extract the following fields about the domain: registrar name, creation date (ISO), expiration date (ISO), and a comma-separated list of nameservers.",
  "schema": {
    "registrar": "string",
    "created": "string",
    "expires": "string",
    "nameservers": "string"
  }
}

Predicate

A registrar transfer is the most actionable signal:

{ "type": "field_changes", "field": "registrar" }

To also catch nameserver moves (a strong "the site is being rebuilt elsewhere" signal):

{
  "type": "composite",
  "operator": "OR",
  "conditions": [
    { "type": "field_changes", "field": "registrar" },
    { "type": "field_changes", "field": "nameservers" }
  ]
}

Create the monitor

curl -X POST https://api.verid.dev/v1/monitors \
  -H "Authorization: Bearer vrd_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "WHOIS - brand.com",
    "url": "https://lookup.icann.org/en/lookup?name=brand.com",
    "schedule_interval_seconds": 86400,
    "extract_config": {
      "method": "prompt",
      "prompt": "From this WHOIS lookup page, extract the following fields about the domain: registrar name, creation date (ISO), expiration date (ISO), and a comma-separated list of nameservers.",
      "schema": {
        "registrar": "string",
        "created": "string",
        "expires": "string",
        "nameservers": "string"
      }
    },
    "diff_predicate": {
      "type": "composite",
      "operator": "OR",
      "conditions": [
        { "type": "field_changes", "field": "registrar" },
        { "type": "field_changes", "field": "nameservers" }
      ]
    },
    "deliveries": [
      { "type": "email", "to": "brand-protection@example.com" }
    ]
  }'

SDK:

import { VeridClient } from '@verid.dev/sdk';

const client = new VeridClient({ apiKey: 'vrd_your_api_key' });

await client.monitors.create({
  name: 'WHOIS - brand.com',
  url: 'https://lookup.icann.org/en/lookup?name=brand.com',
  schedule_interval_seconds: 86400,
  extract_config: {
    method: 'prompt',
    prompt:
      'From this WHOIS lookup page, extract the following fields about the domain: registrar name, creation date (ISO), expiration date (ISO), and a comma-separated list of nameservers.',
    schema: {
      registrar: 'string',
      created: 'string',
      expires: 'string',
      nameservers: 'string',
    },
  },
  diff_predicate: {
    type: 'composite',
    operator: 'OR',
    conditions: [
      { type: 'field_changes', field: 'registrar' },
      { type: 'field_changes', field: 'nameservers' },
    ],
  },
  deliveries: [{ type: 'email', to: 'brand-protection@example.com' }],
});

What the webhook delivers

{
  "id": "del_01H...",
  "fired_at": "2026-05-08T07:00:00Z",
  "diff": {
    "fields_changed": ["registrar", "nameservers"],
    "before": {
      "registrar": "Namecheap, Inc.",
      "created": "2014-03-12",
      "expires": "2027-03-12",
      "nameservers": "ns1.namecheap.com, ns2.namecheap.com"
    },
    "after": {
      "registrar": "GoDaddy.com, LLC",
      "created": "2014-03-12",
      "expires": "2027-03-12",
      "nameservers": "ns1.godaddy.com, ns2.godaddy.com"
    }
  }
}

That's a registrar transfer - a strong signal worth investigating.

Caveats & tips

  • GDPR redaction. EU-registrant domains often hide registrant name and contact info. Registrar, creation, expiry, and nameservers are usually still visible. Adjust your schema based on what the lookup page actually shows.
  • Daily interval, not faster. WHOIS records change rarely. A daily check is the right balance between latency and LLM cost.
  • Some WHOIS lookup pages rate-limit aggressively. If you're monitoring twenty domains, stagger their intervals across the day rather than running them all at the top of the hour.
  • Variants per TLD. brand.com, brand.io, brand.co are separate monitors. Set them up once when you start your brand-protection program.

Related use cases

For policy and regulatory changes, see regulatory filings & policy pages. For terms-of-service drift, see terms of service & privacy policy drift. For tech-stack changes on a competitor domain, see competitor tech stack changes.

Ship this monitor today

5 monitors free, no credit card. Set up takes about a minute.

Get started free