Domain Monitor: Expiry, DNS & Email Security Alerts avatar

Domain Monitor: Expiry, DNS & Email Security Alerts

Pricing

from $2.00 / 1,000 domain-checkeds

Go to Apify Store
Domain Monitor: Expiry, DNS & Email Security Alerts

Domain Monitor: Expiry, DNS & Email Security Alerts

Track domain expiry, registrar, DNS, SPF, DMARC & DKIM for any list of domains. Daily delta: get only what changed. Official RDAP data, no personal info.

Pricing

from $2.00 / 1,000 domain-checkeds

Rating

0.0

(0)

Developer

Rendang Medan

Rendang Medan

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

2 days ago

Last modified

Categories

Share

Domain Monitor (RDAP + DNS)

Watch a list of domain names and be told what changed. Registrar, EPP statuses, creation and expiration dates, name servers, DNSSEC, DNS records and a full e-mail authentication audit (SPF, DMARC, DKIM, MTA-STS, TLS-RPT, BIMI), collected from the official sources only: the registries' RDAP servers (found through the IANA bootstrap registry) and the DNS.

Run it once for an inventory, or schedule it daily with delta mode on: every run compares each domain with the previous run and outputs the changes (registrar transfer, new name servers, MX switched, SPF or DMARC edited, status clientHold added, renewal done...) plus an alert when a domain is about to expire.

No WHOIS scraping, no third-party database, no personal data: contact entities (registrant, administrative, technical, billing) are never read.

Who is it for?

  • IT and security teams: catch an unexpected registrar transfer, name server or MX change (domain hijacking, DNS takeover, forgotten migration) the morning after it happens.
  • Brand protection and legal: monitor a domain portfolio, statuses (locks, holds, pending delete) and expiration dates; never lose a domain to a missed renewal.
  • Agencies and MSPs: one scheduled run per client portfolio, a dataset of changes to forward to Slack, e-mail or your ticketing tool.
  • E-mail deliverability: audit SPF (syntax, all qualifier, the 10 DNS lookup limit), DMARC policy and reporting, DKIM on common selectors, MTA-STS and BIMI for hundreds of domains at once, and be told when someone edits a record.
  • Sales and research: check registration data and mail setup of a list of company domains, without collecting any personal data.

What you get for each domain

FieldDescription
domain, unicodeDomainRegistrable domain in punycode and in Unicode (xn--caf-dma.fr / café.fr).
statusok, not_registered (RDAP 404), rdap_unsupported (the TLD has no RDAP server at IANA: DNS data only) or error.
registrar{ "name", "ianaId" } of the sponsoring registrar. Nothing else from the registrar entity.
statuses, eppStatusesRDAP statuses (client transfer prohibited...) and their EPP codes (clientTransferProhibited...).
createdAt, updatedAt, expiresAtRegistration events, normalised to UTC ISO 8601.
daysUntilExpiration, expiryAlertDays left, and true when below your threshold.
nameServersName servers at the registry (RDAP).
dnssecsigned, from the RDAP secureDNS object and the DS records in DNS.
dns.recordsA, AAAA, MX, NS, TXT, CNAME, CAA, SOA, parsed into clean values.
emailAuthSPF, DMARC, DKIM, MTA-STS (policy file included), TLS-RPT, BIMI, and a list of issues with a severity.
changed, changeTypes, changes, changeSummaryWhat moved since the previous run (delta mode).
firstSeen, previousCheckedAtBaseline information for delta mode.
rdap, errorWhich RDAP server answered, HTTP status, attempts, and the error when there is one.

Change types

registrar_changed, nameservers_changed, mx_changed, spf_changed, dmarc_changed, status_changed, expiration_changed, dnssec_changed, domain_registered, domain_not_registered, dns_records_changed (for the extra record types you choose to track), expiring_soon and expired.

expiring_soon is raised when a domain enters the alert window (30 days by default) and again at 14, 7, 3 and 1 days, not on every run. A field that could not be measured in a run (registry down, DNS timeout) keeps its last known value and never produces a false "removed" change.

Input example

{
"domains": [
"example.com",
"https://www.iana.org/about",
"AFNIC.fr",
"café.fr",
"mail.denic.de"
],
"deltaMode": true,
"onlyChanged": false,
"expiryAlertDays": 30,
"stateStoreName": "my-portfolio",
"extraTrackedRecordTypes": ["CAA"],
"dkimSelectors": ["selector1", "selector2", "google"]
}

URLs, e-mail addresses, upper case, sub-domains and internationalised names are accepted. Each value is reduced to its registrable domain with the embedded Public Suffix List (https://shop.example.co.uk/x becomes example.co.uk) and duplicates are checked once.

Main options:

  • deltaMode (default true): keep the state in a key-value store and report changes. Use one store per watch list. Pick it in stateStore (works with the Actor's limited permissions, see below) or give a name in stateStoreName (needs full permissions).
  • onlyChanged: write only changed domains, first-seen domains and failures to the dataset.
  • expiryAlertDays: alert threshold in days (0 disables it).
  • includeRdap, includeDns, includeEmailAuth, dnsRecordTypes: choose what to collect.
  • maxConcurrency, rdapMaxConcurrencyPerServer, rdapMinDelayMs, maxRetries: politeness. The defaults (2 parallel requests and 300 ms spacing per registry) are gentle on purpose.
  • dnsMode: auto (standard DNS, DNS over HTTPS as a fallback), system or doh.
  • rdapServerOverrides: advanced, map a TLD to an RDAP server that IANA does not list yet.

Output example

One dataset item per domain (shortened):

{
"domain": "example.com",
"unicodeDomain": "example.com",
"status": "ok",
"billable": true,
"checkedAt": "2026-10-12T06:00:04Z",
"registered": true,
"registrar": { "name": "RESERVED-Internet Assigned Numbers Authority", "ianaId": "376" },
"statuses": ["client delete prohibited", "client transfer prohibited", "client update prohibited"],
"eppStatuses": ["clientDeleteProhibited", "clientTransferProhibited", "clientUpdateProhibited"],
"createdAt": "1995-08-14T04:00:00Z",
"updatedAt": "2026-08-14T07:01:39Z",
"expiresAt": "2027-08-13T04:00:00Z",
"daysUntilExpiration": 305,
"expiryAlert": false,
"nameServers": ["a.iana-servers.net", "b.iana-servers.net"],
"dnssec": { "signed": true, "rdapDelegationSigned": true, "dsRecordPresent": true },
"dns": {
"status": "ok",
"resolver": "udp",
"records": {
"A": ["192.0.2.10"],
"MX": [{ "priority": 0, "exchange": "." }],
"NS": ["a.iana-servers.net", "b.iana-servers.net"],
"TXT": ["v=spf1 -all"],
"SOA": { "primaryNameServer": "ns.icann.org", "serial": 2026081401, "refresh": 7200, "retry": 3600, "expire": 1209600, "minimum": 3600 }
}
},
"emailAuth": {
"spf": { "status": "ok", "present": true, "record": "v=spf1 -all", "allQualifier": "fail", "dnsLookups": 0 },
"dmarc": { "status": "ok", "present": true, "policy": "reject", "record": "v=DMARC1;p=reject;sp=reject;adkim=s;aspf=s" },
"dkim": { "status": "not_found", "selectorsFound": [] },
"mtaSts": { "status": "missing", "present": false },
"bimi": { "present": false },
"issueCodes": []
},
"firstSeen": false,
"previousCheckedAt": "2026-10-11T06:00:03Z",
"changed": true,
"changeTypes": ["nameservers_changed"],
"changeSummary": "Name servers at the registry changed: added c.iana-servers.net; removed b.iana-servers.net",
"error": null
}

Values above are illustrative. A failed domain gives one item with status: "error", billable: false and an error object (code, message), for example rdap_rate_limited or dns_failed. A run summary (counters by status and by change type) is saved in the default key-value store under SUMMARY.

The dataset has five views in Apify Console: Overview, Changes, E-mail authentication, DNS records and Statuses and errors.

Daily monitoring in three steps

  1. Create a Task of this Actor with your domain list, deltaMode on and a dedicated stateStoreName (for example client-acme).
  2. In Schedules, run the task every day, for example with the cron expression 0 6 * * *. The first run builds the baseline; from the second run on, changes lists what moved.
  3. Add an integration on the task (Slack, e-mail, Zapier, Make, webhook) triggered when a run succeeds, and read only the changed domains:
GET https://api.apify.com/v2/datasets/{datasetId}/items?view=changes&clean=true

With onlyChanged on, the dataset contains only the changes, so the notification can forward it as is.

Data sources and privacy (GDPR)

  • Sources: RDAP servers of the registries, found through the IANA bootstrap file https://data.iana.org/rdap/dns.json (cached 24 hours), and the public DNS. No WHOIS, no scraping of registrar websites.
  • No personal data by design: from RDAP, only the entity with the registrar role is read, and only its name and IANA ID. Registrant, administrative, technical, billing, reseller and abuse entities are skipped by the parser and never stored. The RNAME of the SOA record (a mailbox) is dropped.
  • E-mail addresses in DNS (DMARC rua, CAA iodef, TXT records) are masked by default (jane@corp.com becomes ***@corp.com); changes are still detected through a fingerprint of the original record.
  • The state store contains only the comparable fields listed above, in your own Apify account.
  • You remain responsible for the lawful use of the results, for example when you monitor domains that belong to individuals.

Limits, honestly

  • Not every TLD publishes everything. Some ccTLD registries publish no registrar or no expiration date over RDAP (.de publishes neither, for instance): those fields are null.
  • Some TLDs have no RDAP service registered at IANA. They are reported as rdap_unsupported with DNS data only; the run does not fail. If a registry runs RDAP without being listed, use rdapServerOverrides.
  • Registry rate limits: registries throttle RDAP. The Actor honours Retry-After, backs off and spaces its requests per server, but a very large list on a single TLD takes time, and a registry that keeps refusing gives error items (not charged).
  • DKIM cannot be proven absent: selectors are arbitrary names. Only the selectors you list (and a built-in list of common ones) are tested.
  • DNS answers come from the resolver used by the run (the platform resolver, or DNS over HTTPS as a fallback). Geo-dependent answers (CDNs) may differ from what your users see. Tracking A or AAAA changes behind a CDN is noisy, which is why only NS, MX, SPF and DMARC are tracked by default.
  • Registrable domain, not host: blog.example.com is checked as example.com. Private suffixes of the Public Suffix List (such as github.io) are not treated as registries.
  • Delta mode needs the same store: changing stateStore or stateStoreName starts a new baseline.
  • Permissions: this Actor runs with limited permissions, which cannot open a store by name. Select a key-value store of your account in the stateStore field; the run is then allowed to read and write that store only. stateStoreName is used only when stateStore is empty and the Actor has full permissions. Without either, the run still succeeds, with delta mode turned off.
  • This is a monitoring tool, not a legal proof of ownership.

FAQ

Why RDAP and not WHOIS? RDAP is the standard that replaced WHOIS for gTLDs (ICANN retired the WHOIS obligation in January 2025): structured JSON, documented error codes, and redaction built in.

Can I check 50,000 domains? Yes. The state store is sharded, concurrency is bounded and the spending limit is respected. Plan for registry rate limits: a few domains per second per registry.

What happens if a registry is down during a run? Its domains are reported as error (not charged) and their last known state is kept, so the next successful run compares with the right baseline.

Changelog

See CHANGELOG.md.