Domain Watch: Expiry, DNS and Certificate Change Alerts
Pricing
from $2.50 / 1,000 domain returneds
Domain Watch: Expiry, DNS and Certificate Change Alerts
Domain expiry and DNS change monitor: check when a list of domains expires, get alerts when A, MX, nameserver or TXT records change, plus an SSL certificate expiry monitor. One row for each domain. Scheduled: only domains with something new are returned and billed. To Google Sheets or n8n.
Pricing
from $2.50 / 1,000 domain returneds
Rating
0.0
(0)
Developer
Adriana Voss
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
18 hours ago
Last modified
Categories
Share
Give it a list of domains and get one row per domain: when the registration expires, who the registrar is, the A, MX, NS and TXT records, and the SSL certificate the site serves today. Run the same list on a schedule and each row also tells you what changed since the last run, so an expiring domain, a swapped nameserver or a certificate that did not renew reaches you before your customers notice. No API key, no account, no proxy.
Who it's for
- Agencies and freelancers who look after client domains and do not want to learn about a lapsed registration from the client.
- IT and operations teams who need a daily answer to "did anything about our domains change?" without paying for a monitoring suite.
- Security teams watching for an unexpected nameserver, MX or TXT change, which is what a domain hijack or a mail redirection looks like from outside.
- Domain investors and brand owners tracking when names they care about come close to expiry or move into a redemption or pending-delete status.
What you get
One flat row per domain:
| What | Columns |
|---|---|
| The verdict | monitorStatus, hasChanges, changeCount, changeTypes, changeSummary, changes, alerts, previousCheckedAt |
| Registration | registeredDomain, registrar, registeredAt, expiresAt, daysUntilExpiry, domainStatus, registrationStatus |
| DNS | dnsA, dnsMx, dnsNs, dnsTxt, dnsStatus |
| Certificate | certIssuer, certIssuerName, certSubject, certValidFrom, certExpiresAt, certDaysUntilExpiry, certTrusted, certFingerprint, certificateStatus |
| Provenance | domain, sourceUrl, scrapedAt |
Two example rows from a scheduled run, shortened:
| domain | monitorStatus | changeSummary | expiresAt | daysUntilExpiry | certIssuer | certDaysUntilExpiry |
|---|---|---|---|---|---|---|
| example.com | CHANGED | MX records changed: added 10 mail.example.com; removed 0 .. | 2027-08-13T04:00:00Z | 305 | SSL Corporation | 75 |
| example.org | CHANGED | Domain registration expires in 19 days, on 2026-10-31. | 2026-10-31T00:00:00Z | 19 | Let's Encrypt | 41 |
changes carries the detail behind the sentence: for every change its type, the field, the previous
value and the current value.
What counts as a change
changeTypes value | Fires when |
|---|---|
domain-expiring, domain-expired | the registration is inside your warning window, in its last 7 days, or past its expiry date |
certificate-expiring, certificate-expired | the same, for the certificate the site serves |
domain-expiry-changed | the expiry date moved, which is what a renewal looks like |
registrar-changed | the domain was transferred to another registrar |
domain-status-changed | the registry status list changed, for example to pending delete |
dns-a-changed, dns-mx-changed, dns-ns-changed, dns-txt-changed | a record was added or removed |
certificate-issuer-changed | the certificate now comes from a different authority |
certificate-renewed | the served certificate has a later expiry date than before |
Expiry warnings need no earlier run: a domain that expires in 12 days says so the first time you
check it. Each warning is reported once when it starts and once more when the last 7 days begin, not
every day in between. alerts lists every warning that is active right now on every run.
How change tracking works
- A plain run (the default) returns every domain with its current state and its active expiry warnings. The change columns are empty because nothing is remembered.
- Turn on "Only return domains with something new" and the run remembers each domain. The first
run returns every domain as
BASELINE, so you can see what was recorded. From then on a domain is returned only when something changed or a new warning fired. A quiet domain is not returned and not charged. - Give the watchlist a name to keep two lists apart, or to track changes while still getting
every domain back on every run (
NO_CHANGErows included).
Three rules keep the alerts honest:
- An outage is not a change. If a registry, a resolver or the site itself does not answer on one run, that part of the remembered state is left as it was and nothing is reported. The next run that does get an answer compares against the last value actually seen.
- Order and timing are not changes. Records are compared as sorted sets, and TTLs are ignored.
- Rotating IP addresses can be switched off. A site behind a CDN or load balancer may hand out a different A record on every lookup. Untick "Watch A records" for such a list and only MX, NS and TXT changes are reported.
How to use Domain Watch
- In the Apify Console. Open the actor page and click Start — the
domainsfield is already pre-filled with a working example. Results land in the run's dataset as soon as each item is found. - Via the API. Call it directly with a POST request — no Console needed once you have an API token:
curl "https://api.apify.com/v2/acts/accountable_eel~domain-watch-alerts/run-sync-get-dataset-items?token=<YOUR_TOKEN>" \-X POST \-H "Content-Type: application/json" \-d '{"domains":["example.com","github.com"]}'
- On a schedule. Save this actor as an Apify Task with the input you want, then add a Schedule (hourly, daily, weekly) so it runs on its own — no server of your own required.
Input
{"domains": ["example.com","github.com"]}
One domain per line. Each one is checked for its registration and expiry date, its DNS records and the certificate it serves. Run the same list on a schedule and every row tells you what changed since the run before. Accepted formats: example.com, https://www.github.com, api.example.com.
Output
One row per domain, for example:
| query | found | status | domain | sourceUrl | monitorStatus | hasChanges | changeCount | changeTypes | changeSummary | changes | alerts | previousCheckedAt | registeredDomain | registrar | registeredAt | expiresAt | daysUntilExpiry | domainStatus | registrationStatus | dnsA | dnsMx | dnsNs | dnsTxt | dnsStatus | certIssuer | certIssuerName | certSubject | certValidFrom | certExpiresAt | certDaysUntilExpiry | certTrusted | certFingerprint | certificateStatus | scrapedAt |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| example.com | true | OK | <changes (full detail)> | <certificate fingerprint (sha-256)> | 1970-01-01T00:00:00.000Z |
A name that is not registered and does not resolve comes back as a row with "found": false and a
message that says so. It is never charged.
Example runs
Three inputs that need no credentials of any kind and return rows as they stand. Paste one into the Input tab and press Start.
1. Where do these domains stand today?
{"domains": ["example.com", "github.com"],"expiryWarnDays": 60}
2. A daily watch that only returns what is new
Save this as a task and put it on a daily schedule. The first run returns both domains as the baseline; later runs return a domain only when something changed.
{"domains": ["example.com", "github.com"],"onlyNewSinceLastRun": true,"deltaName": "my-domains","expiryWarnDays": 30,"certExpiryWarnDays": 14}
3. A mail and nameserver watch for a domain behind a CDN
{"domains": ["github.com"],"onlyNewSinceLastRun": true,"deltaName": "mail-and-ns","watchARecords": false}
Pricing
Pay-per-event. A flat per-run fee covers session/proxy warmup; each independent
source is billed under its own event, only when that source actually returns
data — see .actor/pay_per_event.json for exact prices. A miss is never
charged.
You pay once per domain row returned, and nothing else:
- A domain that is not registered and does not resolve is free.
- A domain no check could read on this run is free.
- With "Only return domains with something new" on, a domain where nothing changed is not returned and is free. A watchlist of 200 quiet domains costs the start fee and nothing more.
Use it from Clay, n8n, Make, or an AI agent
This actor runs synchronously over plain HTTP — call it directly from a script, a workflow tool, or an AI agent, no Apify Console needed once you have an API token.
curl "https://api.apify.com/v2/acts/accountable_eel~domain-watch-alerts/run-sync-get-dataset-items?token=<YOUR_TOKEN>" \-X POST \-H "Content-Type: application/json" \-d '{"domains":["example.com","github.com"]}'
n8n. Add an HTTP Request node: Method POST, URL https://api.apify.com/v2/acts/accountable_eel~domain-watch-alerts/run-sync-get-dataset-items?token=<YOUR_TOKEN>, Body Content Type JSON, JSON Body {"domains":["example.com","github.com"]} (swap in an expression from an earlier node for a real value).
Clay. Add an "HTTP API" column: Method POST, URL https://api.apify.com/v2/acts/accountable_eel~domain-watch-alerts/run-sync-get-dataset-items?token=<YOUR_TOKEN>, Body {"domains":["{{domain}}"]}, mapping the row's domain into the domains array.
MCP. In Claude, Cursor, or any MCP client with the Apify MCP server, ask for "domain expiry and DNS change monitor" — the agent will find and run this actor.
Where the data comes from
- Registration and expiry come from RDAP, the registries' own machine-readable successor to WHOIS. Each domain is looked up at the registry that runs its ending.
- DNS records come from two public DNS-over-HTTPS resolvers, the second used when the first does not answer.
- The certificate is read by connecting to the domain on port 443 the way a browser does. It is the certificate the site is serving right now, which is the one whose expiry can take it down.
Limits, stated plainly
- Many country domains publish no RDAP data. For those the registration columns are empty and
registrationStatussaysNO_RDAP_SERVER. DNS and certificate watching work for every domain. - Expiry dates are the registry's. A registrar may keep a domain alive for a grace period after the date shown, and a registry may show a date one year ahead during auto-renewal.
- One certificate per check. A large site may serve different certificates from different servers. Only a certificate with a later expiry date than the remembered one is reported as a renewal, so those sites do not produce a stream of alerts.
- A host with no HTTPS has empty certificate columns and
certificateStatus: NO_TLS. - Changes are detected between runs. A record that changed and changed back between two runs is not seen. Run more often if that matters.
- No registrant or contact details. This actor returns nothing about who owns a domain.
Data & privacy
Everything returned is public infrastructure data: registry records, DNS records and the certificate a server presents to every visitor. The actor reads no registrant, administrative or technical contact, so it returns no personal data. The state it remembers between runs is stored in a key-value store in your own Apify account, under the watchlist name you chose.
FAQ
Why did my first scheduled run return every domain? The first run of a domain is its baseline. It is returned so you can see what was recorded. From the second run on, only domains with something new are returned.
Why is expiresAt empty for my domain?
Its registry publishes no RDAP data. This is common for country endings. The DNS and certificate
columns are still filled and still watched.
Can I watch a host such as api.example.com?
Yes. DNS and the certificate are checked for the host you gave; registration is looked up for the
registered name above it, shown in registeredDomain.
Will I get the same expiry warning every day?
No. A warning is reported when it starts and again when the last 7 days begin. alerts still lists
it on every row while it is active.
Do I need a proxy? No.
Related actors
-
WHOIS & RDAP Lookup: Bulk Domain Age, Expiry & Registrar: bulk domain age, expiry and registrar in one run.
-
Domain RDAP Lookup for a one-off registration record.
-
DNS Record Lookup for one record type with email-security columns.
-
TLS Certificate Lookup for the history of certificates issued for a domain.
-
Domain Availability Check for whether a name is free to register.