Domain Expiry, WHOIS & DNS Lookup: Failed Runs Cost Nothing avatar

Domain Expiry, WHOIS & DNS Lookup: Failed Runs Cost Nothing

Pricing

from $0.42 / 1,000 domain looked ups

Go to Apify Store
Domain Expiry, WHOIS & DNS Lookup: Failed Runs Cost Nothing

Domain Expiry, WHOIS & DNS Lookup: Failed Runs Cost Nothing

Domain expiry dates, days left, registrar, EPP status, nameservers and DNSSEC from the registries over RDAP (not WHOIS), plus live DNS records, for up to 2,000 domains. Says whether registry and live nameservers agree. A failed or empty run costs nothing. Free dry run, spend cap, no start fee.

Pricing

from $0.42 / 1,000 domain looked ups

Rating

0.0

(0)

Developer

Monty Burrows

Monty Burrows

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

a day ago

Last modified

Share

Domain Registration, Expiry & DNS Lookup

Give it a list of domains. Every run returns one row per domain: the registrar, the EPP status codes, the registration and expiry dates, how many days are left, the nameservers and whether it is DNSSEC-signed. The same row carries what the domain actually resolves to right now, and a column that says whether those two agree.

Read straight from the registries over RDAP, the protocol ICANN requires them to publish, and from live DNS over DNS-over-HTTPS. No login, no API key, no screen scraping.

Paste a hostname and it is reduced to the domain its registry actually holds: www.example.com is looked up as example.com, because a registry has no record of the first and would return the same 404 it returns for a name nobody has registered.

No per-run fee, and no contact details, ever. See below, because that second one is a deliberate limitation as much as it is a promise.


What it is for

Set it on a daily schedule over your domain portfolio and sort by Days left. That is the whole product, and 200 domains checked every day costs about $3.60 a month.

It also answers, as a by-product:

  • Is this name available? A registry with no record returns exactly that.
  • Who is it registered with, and when does it move? registrar, and the EPP status codes that say whether a transfer or a delete is locked.
  • Where does it point, and is that where it should? dnsA, dnsMx, dnsNs and the rest, and delegationStatus (see the next section).
  • Has anything changed? nameservers, dnssecSigned and lastChangedAt, on every run.

Two readings of the same domain, on one row

RDAP tells you what the registry holds. DNS tells you what the world actually sees. Most of the time they say the same thing, and the interesting moments are the ones where they do not.

delegationStatus is the column that says so, and it is the one thing on this row that neither half could produce on its own. It is graded rather than a yes/no, because the registry's delegation and your zone's own NS records are allowed to differ and routinely do:

It saysWhat it meansWorth acting on
matchThe same set of nameservers on both sidesNo
extraYour zone publishes the registry's servers, and more besidesRarely
partialThey overlap, but each has one the other lacksUsually (see below)
mismatchNothing in common. The domain now answers from somewhere elseYes
emptyOne side had nothing to compare. Not a disagreementNo

Why graded and not a tick box: of nine established domains checked on 2026-09-23, eight matched exactly and github.io did not. Identity Digital holds five nameservers for it and the zone publishes eight, those five among them. Both are correct, and a boolean would have reported GitHub's own domain as suspicious. partial is the quieter one worth looking at: it means the registry still delegates to a nameserver your zone no longer lists, which is how a lame delegation starts.

You also get the records themselves: A, MX and NS by default, and AAAA, TXT, CAA and SOA if you tick them. They are included in the price. Each extra record type is one more request per domain, so asking for all seven makes a run slower, not dearer.

There is no CNAME, and that is deliberate. Every name here is looked up as a registrable domain, and a domain that resolves is a zone apex, which cannot carry a CNAME at all. It came back empty on all 36 domains tried, including every apex-aliasing platform. A column that can never be filled is not worth the space in your spreadsheet.

Clear the field entirely and you get a pure registry lookup, with the DNS columns left empty.


No registrant contact data. Ever.

This is worth a section because it cuts both ways.

For .com, .net, .org and the other gTLDs it costs you nothing: post-GDPR the registries redact the registrant entirely, so there is nothing to collect. Every domain in a sample of eight returned the registrar and no one else.

Some country-code registries are different. .fr publishes, with nothing redacted:

a name, an organisation, a postal address, an email address and a telephone number

for the registrant, the administrative contact and the technical contact. For a company those are corporate details. For a domain registered by an individual they are that person's home address and phone number.

This Actor reads none of it. The only entity it touches is the registrar, because a registrar is a company by definition. If you need registrant contact details, this is not the Actor. That is a decision, not an oversight.

There is one switch that changes this and it is off by default: Include the raw RDAP document adds the registry's whole response to each row, contacts and all. The listing tells you what is in it; what you do with it is yours.


Coverage, which is the real limitation

RDAP is discovered from IANA's own bootstrap file, fetched live on every run rather than pinned to a stale copy. On 2026-09-16 it listed 1,202 TLDs.

Every gTLD (.com, .net, .org, .app, .dev and 1,100 more)Covered
Country-code TLDs in IANA's bootstrap71 of roughly 250
Added by hand, each verified by a live lookup.io .de .us .ch
Not covered.co .eu .jp .cn .ru .me .se .it .es and most of Europe

Bootstrapping is voluntary for country-code registries and most have not done it. A domain on an uncovered TLD gets a row saying exactly that, with the reason. It also gets its live DNS records, which for those domains are the only reading anyone can give you.

Run a free dry run first. It tells you how many of your domains are on a covered TLD and how many are not, before you are charged for any of them. If half your portfolio is .co, you will know in one free run rather than after a bill.


What you get

The 12 of 20 SaaS company domains that expire soonest, with days left, expiry date, registrar and EPP status, from a real run

A finished run's results in the Apify Console, in table view, with the Expiry, Overview, Delegation, DNS records and Coverage views

GroupFields
ExpiryexpiresAt, daysUntilExpiry, registeredAt, lastChangedAt
Registrationregistrar, registrarIanaId, statuses, isRegistered, outcome
Delegationnameservers (registry), dnsNs (live), delegationStatus
Live DNSdnsA, dnsAaaa, dnsMx, dnsTxt, dnsCaa, dnsSoa
DNS statusdnsStatus (ok, nxdomain, failed), dnsTruncated, dnssecSigned
Identitydomain, tld, ldhName, unicodeName
ProvenancerdapServer, rawRecord, detail, scrapedAt, sourceUrl, runId, id

Read dnsStatus before believing an empty DNS column. An empty dnsMx on a row whose dnsStatus is ok means the domain takes no mail. An empty dnsMx on a row whose dnsStatus is empty means nobody asked.

Not every registry publishes an expiry date

This is the one caveat on the headline use case and it is a real one, not a theoretical one:

  • auDA (.au) publishes only a last-changed date.
  • DENIC (.de) publishes a single event.

expiresAt and daysUntilExpiry are empty on those, and the run report counts how many rows are in that position. An expiry monitor cannot promise this column for every TLD, and this one does not pretend to.


Pricing

From $0.42 per 1,000 domains, and nothing else. No per-run fee, no charge for compute or retries, and no separate charge for the DNS half: one price covers both readings.

Your Apify planPer domainPer 1,000 domains
Free$0.0006$0.60
Bronze$0.00054$0.54
Silver$0.00048$0.48
Gold$0.00042$0.42
Platinum$0.00042$0.42
Diamond$0.00042$0.42

A finished dry run in the Apify Console: its status line reads "Dry run: about 20 results for roughly $0.0120. Nothing was charged."

The status line is the estimate. A dry run writes no rows, so its results table stays empty, and it charges nothing.

A real dry run's estimate: 20 domains for $0.0120 against caps of 20 results and $0.05, with $0.00 charged, beside the three billing rules

How a run becomes a bill: your domains are looked up over RDAP and live DNS, held in a ledger, every row is checked, and only a run that passes is charged

The start fee is the part worth comparing

A domain portfolio is checked on a schedule (that is what an expiry monitor is), so a per-run fee is levied every day, forever. Measured 2026-09-23:

ActorPer runPer domain
automation-lab/domain-availability-checker$0.035$0.001
perryay/domain-age-history-checker$0.025per domain
ntriqpro/whois-domain-lookuprun-start$0.02
visita/domain-inspectorstart$0.004
santamaria-automations/domain-whois-dns$0.001$0.002
this Actornone$0.0006 to $0.00042

At $0.035 a start, a daily check costs $12.78 a year before a single domain is looked up.

What it costs in practice

What you are doingRowsCost
200 domains, once200$0.12
200 domains, daily200 a runabout $3.60 a month
2,000 domains, weekly2,000 a runabout $5.20 a month

Every domain is charged, including the ones on TLDs with no RDAP service. That rule needs stating plainly because it is the one you might reasonably object to. The reason it is right: "no RDAP service is published for .co" is a fact about the TLD, read from IANA's own registry, and any RDAP client would return the same answer. It is what tells you to stop trying to monitor those domains this way. The free dry run is where you find out how many of yours those are.

What is never charged is a domain we could not get an answer about: a registry that refused us, throttled us, was down, or replied with something that is not RDAP. Those produce no row at all. And charges settle only after the run succeeds and its health checks pass.


What happens when something changes

Every run is checked against what a healthy run looks like, and a run that fails a check is not billed:

  • Every domain ended in exactly one bucket. On an expiry monitor a domain that silently produced nothing is indistinguishable from one that is not expiring.
  • IANA's bootstrap was read. Without it this Actor would know four TLDs instead of 1,202 and report almost everything as uncovered: nearly free, and completely wrong.
  • No undeclared field reached a row. On this Actor that is not routine schema hygiene: the declared columns are how "no contact data" is enforced.
  • Most answerable domains got an answer, and we are not being refused at scale.
  • The registries still answered in RDAP.
  • The pacing was honoured. One request per second per registry, and note per registry: one server answers for 451 TLDs. The resolver has its own, separate gap.
  • The DNS half actually ran. A run that asked for DNS records and resolved nothing fails. A resolver that was merely unreachable for most of the list warns instead. Your registry columns are unaffected, and a correct registry reading should not be refunded because a second, supplementary one was unavailable.

Limits

  • 2,000 domains per run, one request each to its registry, plus one per DNS record type, plus one for IANA's bootstrap.
  • One row per registrable domain. A hostname is reduced to it, so example.com and www.example.com in one list are one lookup and one charge. The DNS columns describe the registrable name, not the hostname you pasted.
  • The DNS reading is a public resolver's view, not yours. It is what Cloudflare's 1.1.1.1 resolves, which is the right answer for "is this domain delegated where I think it is" and the wrong one for anything depending on split-horizon DNS or your own network's resolver.
  • A dry run resolves nothing. Its count is exact and does not depend on DNS, so it does not spend anyone's resolver to produce a number it already knows.
  • .co, .eu and most of Europe are not covered. See above. Check with a free dry run.
  • No expiry date from some registries, including .au and .de.
  • No registrant, administrative, technical or billing contact, by design.
  • RDAP only, no WHOIS. The old port-43 protocol covers more TLDs and is an unparseable mess of per-registry text formats. This Actor reads the structured one and tells you where it cannot.
  • It keeps no state between runs. Every run returns the current reading; you decide what changed. GROUP BY domain ORDER BY scrapedAt is a better diff than any this Actor could impose.

Run it on a schedule

Save your input as a task and add an Apify Schedule to run it daily, weekly or hourly. When a run finishes, Apify's integrations can pass its rows to Google Sheets, Zapier, Make or n8n, and a webhook can call your own endpoint. A run that fails costs nothing and does not fire an integration or webhook set to run on success.

This is what it is for. Every run reads every domain on the list again, so a daily schedule sorted by Days left is an expiry monitor, and 200 domains checked daily costs about $3.60 a month. nameservers, dnssecSigned and lastChangedAt come back on every run, for spotting what changed.

Use it from an AI agent

Apify's MCP server loads this Actor as a single tool:

https://mcp.apify.com/?tools=montyburrows/domain-rdap

An agent with it can run the Actor with the same inputs as the form, dry run and spend cap included, and read the registry and DNS answers it returns, billed to your Apify account at the prices above.

FAQ

How much does it cost to check domain expiry dates?

$0.60 per 1,000 domains on Apify's free plan, and $0.42 per 1,000 on Gold and above, with no start fee and the DNS records included. Apify's free plan gives $5 of usage a month, which at $0.0006 a domain is about 8,333 domains. Every domain answered is charged, including one on a TLD with no RDAP service. A domain no registry would answer about produces no row and no charge, a failed run and an empty run cost nothing, and the dry run is free and tells you how many of your domains are covered before you pay for any.

This Actor reads RDAP, the protocol ICANN requires registries to publish, and live DNS over DNS-over-HTTPS, with no login and no API key. It reads no registrant contact data: the only entity it touches is the registrar. The one exception is Include the raw RDAP document, off by default, which adds the registry's whole response, contacts and all. Whether a particular use is lawful depends on what you do with the data and where you are, and nothing here is legal advice.

Is this a WHOIS lookup?

It answers the questions people use WHOIS for (registrar, dates, status and nameservers), read over RDAP rather than WHOIS. WHOIS covers more TLDs in a different text format for each registry; RDAP is structured, and this Actor says where it cannot reach.

Which TLDs does it cover?

Every gTLD, the 71 country-code TLDs in IANA's bootstrap, and .io, .de, .us and .ch added by hand. .co, .eu, .jp and most of Europe are not covered; those domains still get a row saying so, with their live DNS.

Why is the expiry date empty for some domains?

Some registries do not publish one: .au publishes only a last-changed date and .de a single event. The run report counts how many rows are in that position.

Can it tell me whether a domain is available?

A registry with no record of a name returns exactly that, and isRegistered says so on the row.

Other Actors from this developer

Every one has the same free dry run and spend cap, and none charges for a failed run.

Support and feature requests

Need a TLD adding, or another field? Email actors@montyburrows.com. Feature requests are welcome: a ccTLD whose registry runs RDAP is usually a one-line change.