Domain Monitor: Expiry, DNS & Email Security Alerts
Pricing
from $2.00 / 1,000 domain-checkeds
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
Maintained by CommunityActor 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,
allqualifier, 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
| Field | Description |
|---|---|
domain, unicodeDomain | Registrable domain in punycode and in Unicode (xn--caf-dma.fr / café.fr). |
status | ok, 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, eppStatuses | RDAP statuses (client transfer prohibited...) and their EPP codes (clientTransferProhibited...). |
createdAt, updatedAt, expiresAt | Registration events, normalised to UTC ISO 8601. |
daysUntilExpiration, expiryAlert | Days left, and true when below your threshold. |
nameServers | Name servers at the registry (RDAP). |
dnssec | signed, from the RDAP secureDNS object and the DS records in DNS. |
dns.records | A, AAAA, MX, NS, TXT, CNAME, CAA, SOA, parsed into clean values. |
emailAuth | SPF, DMARC, DKIM, MTA-STS (policy file included), TLS-RPT, BIMI, and a list of issues with a severity. |
changed, changeTypes, changes, changeSummary | What moved since the previous run (delta mode). |
firstSeen, previousCheckedAt | Baseline information for delta mode. |
rdap, error | Which 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(defaulttrue): keep the state in a key-value store and report changes. Use one store per watch list. Pick it instateStore(works with the Actor's limited permissions, see below) or give a name instateStoreName(needs full permissions).onlyChanged: write only changed domains, first-seen domains and failures to the dataset.expiryAlertDays: alert threshold in days (0disables 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),systemordoh.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
- Create a Task of this Actor with your domain list,
deltaModeon and a dedicatedstateStoreName(for exampleclient-acme). - 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,changeslists what moved. - 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
registrarrole 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. TheRNAMEof the SOA record (a mailbox) is dropped. - E-mail addresses in DNS (DMARC
rua, CAAiodef, TXT records) are masked by default (jane@corp.combecomes***@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 (
.depublishes neither, for instance): those fields arenull. - Some TLDs have no RDAP service registered at IANA. They are reported as
rdap_unsupportedwith DNS data only; the run does not fail. If a registry runs RDAP without being listed, userdapServerOverrides. - 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 giveserroritems (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
AorAAAAchanges behind a CDN is noisy, which is why only NS, MX, SPF and DMARC are tracked by default. - Registrable domain, not host:
blog.example.comis checked asexample.com. Private suffixes of the Public Suffix List (such asgithub.io) are not treated as registries. - Delta mode needs the same store: changing
stateStoreorstateStoreNamestarts 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
stateStorefield; the run is then allowed to read and write that store only.stateStoreNameis used only whenstateStoreis 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.