Bulk Domain WHOIS/RDAP Lookup: Expiry, Availability & DNS avatar

Bulk Domain WHOIS/RDAP Lookup: Expiry, Availability & DNS

Pricing

from $1.20 / 1,000 domain looked up (registered or not found)s

Go to Apify Store
Bulk Domain WHOIS/RDAP Lookup: Expiry, Availability & DNS

Bulk Domain WHOIS/RDAP Lookup: Expiry, Availability & DNS

Bulk WHOIS / domain expiry checker on official RDAP: registrar, creation and expiry dates, availability, nameservers, DNS, email provider, SPF and DMARC for thousands of domains. No API key, no contact data.

Pricing

from $1.20 / 1,000 domain looked up (registered or not found)s

Rating

0.0

(0)

Developer

Derek VanLaningham

Derek VanLaningham

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

16 days ago

Last modified

Share

Bulk WHOIS replacement on the official RDAP protocol: registrar, creation and expiry dates, availability, nameservers and DNS for thousands of domains. No API key.

Give it up to 10,000 domains (or URLs or email addresses). For each registrable domain it asks the authoritative registry's RDAP server (the ICANN-mandated successor to WHOIS) and, optionally, resolves DNS over HTTPS. You get one clean, typed JSON row per domain.

Ready-to-run examples

Each example below is a published task: open its page and click Try to copy it into your account and run it, or paste the JSON into the Input tab (JSON view). Times, rows and costs are from real runs on Oct 3, 2026 (FREE-tier prices); results change as the source data changes.

Bulk WHOIS / RDAP Lookup for 10 Domains: Registrar and Expiry

Open this example: 3 s, 10 rows, $0.022.

{"domains":["stripe.com","github.com","wikipedia.org","bbc.co.uk","shopify.com","mozilla.org","cloudflare.com","nytimes.com","apify.com","this-domain-is-free-7q3x.com"]}

Output excerpt (one row, selected fields):

[
{
"domain": "stripe.com",
"registrationStatus": "registered",
"likelyAvailable": false,
"registrar": "SafeNames Ltd.",
"createdAt": "1995-09-12T04:00:00Z",
"expiresAt": "2027-09-11T04:00:00Z",
"daysUntilExpiry": 342
},
{
"domain": "this-domain-is-free-7q3x.com",
"registrationStatus": "not_found",
"likelyAvailable": true,
"registrar": null,
"createdAt": null,
"expiresAt": null,
"daysUntilExpiry": null
}
]

Domain Expiry, DNS, SPF and DMARC Check for 5 Domains

Open this example: 3 s, 5 rows, $0.017.

{"domains":["stripe.com","shopify.com","mozilla.org","bbc.co.uk","apify.com"],"includeDns":true}

Output excerpt (one row, selected fields):

{
"domain": "stripe.com",
"registrar": "SafeNames Ltd.",
"expiresAt": "2027-09-11T04:00:00Z",
"daysUntilExpiry": 342,
"dns": {
"mx": [
{
"priority": 10,
"host": "aspmx.l.google.com"
},
{
"priority": 20,
"host": "alt1.aspmx.l.google.com"
}
],
"emailProvider": "google_workspace",
"dmarcPolicy": "reject",
"spf": "v=spf1 ip4:198.2.180.60/32 ip4:13.111.2.227/32 include:spf1.…"
}
}

What you get

FieldExample
registrationStatusregistered / not_found / unsupported_tld / error
likelyAvailabletrue = likely available. Premium or reserved names may still be unavailable.
registrar, registrarIanaId, registrarUrlSafeNames Ltd., 447
createdAt, updatedAt, expiresAtISO 8601 UTC, e.g. 1995-09-12T04:00:00Z
ageDays, daysUntilExpiryintegers (negative = already expired)
statuses, transferLockedEPP status codes (client transfer prohibited, …)
nameservers, dnssecSignedlower-case, sorted
dns (optional)A, AAAA, MX, NS, TXT, CNAME, SOA, CAA, email provider, SPF, DMARC policy
registryTermsUrlthe registry's terms of use for this data
inputCounthow many of your entries were merged into this domain (e.g. https://www.stripe.com/jobs + stripe.com → 2)
errorMessagewhy the lookup failed when registrationStatus is error (RATE_LIMITED: <host>, RDAP_ERROR: …, or the registry's message); otherwise null

Example row (stripe.com):

{
"recordType": "domain",
"domain": "stripe.com",
"domainUnicode": "stripe.com",
"input": "stripe.com",
"inputCount": 1,
"tld": "com",
"registrationStatus": "registered",
"errorMessage": null,
"likelyAvailable": false,
"registrar": "SafeNames Ltd.",
"registrarIanaId": "447",
"registrarUrl": null,
"createdAt": "1995-09-12T04:00:00Z",
"updatedAt": "2025-10-01T01:39:51Z",
"expiresAt": "2027-09-11T04:00:00Z",
"rdapDataUpdatedAt": "2026-10-03T15:12:44Z",
"ageDays": 11344,
"daysUntilExpiry": 342,
"statuses": ["client delete prohibited", "client transfer prohibited", "client update prohibited", "server delete prohibited", "server transfer prohibited", "server update prohibited"],
"transferLocked": true,
"nameservers": ["ns-1087.awsdns-07.org", "ns-1882.awsdns-43.co.uk", "ns-423.awsdns-52.com", "ns-705.awsdns-24.net"],
"dnssecSigned": false,
"rdapServer": "https://rdap.verisign.com/com/v1/",
"rdapUrl": "https://rdap.verisign.com/com/v1/domain/stripe.com",
"registryTermsUrl": "https://www.verisign.com/domain-names/registration-data-access-protocol/terms-service/index.xhtml",
"dns": null,
"changes": null,
"isNew": null,
"rawRdap": null,
"scrapedAt": "2026-10-03T15:30:00.000Z"
}

Why this Actor

  • Official sources only. RDAP (the ICANN-mandated WHOIS successor) through the IANA bootstrap registry, plus a few verified extra ccTLD servers (.io, .me, .de, .us). DNS comes from public DNS-over-HTTPS resolvers (Cloudflare, with Google as fallback). No scraping, no logins, no CAPTCHAs.
  • Privacy-safe. No registrant, admin, tech or abuse contact data is ever output. See the FAQ.
  • Availability check. "Not found" in the registry and NXDOMAIN in DNS → likelyAvailable: true.
  • Email provider, SPF and DMARC from DNS (includeDns).
  • Monitor mode. Schedule it and get only the domains whose registration or DNS changed.
  • $2 per 1,000 domains. Unsupported TLDs and errors are free.
  • MCP-ready. Typed, stable camelCase keys that AI agents can use directly.

Use cases

  • Domain portfolio and expiry tracking. Find domains expiring soon, check transfer locks and confirm the registrar.
  • Domain investing and drop-catch research. Check whether names are likely available and when registered names expire.
  • Brand protection. Watch look-alike domains for new registrations or nameserver changes.
  • IT and security audits. Check nameservers, DNSSEC, SPF and DMARC posture across your own estate or your vendors'.
  • Company or account enrichment. Add domain age and email provider to company records, staying within the acceptable-use rules below.
  • AI agents. Answer questions like "When does example.com expire?" or "Is foo.io taken?".

How to do a bulk WHOIS / RDAP lookup and check domain expiry

  1. Paste domains into Domains, one per line: up to 10,000 domains, URLs or email addresses.
  2. Run. Each domain is looked up through its official registry's RDAP API (the modern replacement for WHOIS). You get the registrar, creation date, expiry date, days until expiry, status codes, transfer lock, nameservers, DNSSEC, and whether the domain looks available (not registered).
  3. Check expiry in bulk. Set Expiring within days (e.g. 60) to return only domains that expire soon. Set Only available to keep only unregistered names.
  4. Add DNS (optional). Turn on Include DNS for A, AAAA, MX, NS, TXT, CNAME, SOA and CAA records, plus the detected email provider and the SPF and DMARC policy.
  5. Monitor (optional). Turn on Monitor mode with a Monitor ID and schedule it to get change-detected rows when a registrar, expiry date, status or nameserver changes.
  6. AI agents. Callable as an MCP tool via mcp.apify.com.

Pricing: $2 per 1,000 domains on the Free plan (less on paid plans), $1 per 1,000 for DNS, and $0.002 per run. Example: 10 domains in 2.8 s; 1,000 popular domains in 147 s.

Example inputs

Example 1: a single domain

{ "domains": ["example.com"] }

Example 2: bulk, up to 10,000 domains

{ "domains": ["stripe.com", "wikipedia.org", "bbc.co.uk", "…"], "includeDns": true }

Example 3: expiring soon (only matching rows are charged)

{ "domains": ["…your portfolio…"], "expiringWithinDays": 60 }

Example 4: monitor on a schedule, with a webhook. Create a schedule (for example, daily) with this input:

{ "domains": ["…"], "monitorMode": true, "monitorId": "brand-watch", "includeDns": true }

Then add a webhook for ACTOR.RUN.SUCCEEDED that reads the dataset. Each run outputs only new or changed domains, with a changes list such as [{"field":"nameservers","before":[…],"after":[…]}].

Speed

  • Throughput: roughly 300 .com domains a minute. Each registry is queried at a polite 5 requests/s, and that limit is never raised. Different registries (.com, .org, .uk, .de, …) are queried in parallel, so mixed lists finish faster: 1,000 domains on one registry take about 200 s, and a mixed list takes about as long as its largest single-registry share.
  • Tip for very large .com lists: split them across several runs, for example 2,000 domains each (about 7 minutes per run). Run them one after another, e.g. chained with a schedule or a webhook. Don't run them concurrently: parallel runs against the same registry would exceed its polite rate. You get results sooner, a failed run is cheap to repeat, and Max cost per run keeps each run's cost predictable.

Input reference

FieldTypeDefaultDescription
domainsstring[] (1–10,000)prefilledDomains, URLs or emails
includeDnsbooleanfalseAlso resolve DNS via DoH and derive email provider, SPF and DMARC (+ dns-records event)
dnsRecordTypesstring[]all 8Any of A, AAAA, MX, NS, TXT, CNAME, SOA, CAA (_dmarc TXT is always queried)
expiringWithinDaysinteger 0–36500Output only registered domains expiring within N days (including already expired). Domains without a published expiry date (e.g. .de) are excluded.
onlyAvailablebooleanfalseOutput only domains the registry reports as not found
monitorModebooleanfalseOutput only domains that are new or changed since the last run with the same monitorId
monitorIdstringdefaultName of the monitor history (letters, digits, -)
includeRawRdapbooleanfalseAttach the registry's RDAP JSON with all contact entities removed
proxyConfigurationobjectoffNot needed. Datacenter proxy only, if a registry rate-limits you.

Output reference

Domain row (recordType: "domain"): every key is always present, and null means unknown. See the example above. Notes:

  • tld is the last label of the public suffix (uk for bbc.co.uk).
  • errorMessage is set when registrationStatus is error. Values are RATE_LIMITED: <host>, RDAP_ERROR: <status or reason>, or the registry's own message.
  • inputCount is how many of your entries were reduced to this domain.
  • changes and isNew are filled in monitor mode only.

dns object (includeDns: true):

{
"resolver": "cloudflare",
"a": ["…"], "aaaa": ["…"], "cname": [],
"mx": [{"priority": 10, "host": "aspmx.l.google.com"}],
"ns": ["ns-423.awsdns-52.com"],
"txt": ["v=spf1 include:_spf.google.com ~all"],
"soa": {"mname": "ns-423.awsdns-52.com", "rname": null, "serial": 1},
"caa": ["0 issue \"amazon.com\""],
"emailProvider": "google_workspace",
"spf": "v=spf1 include:_spf.google.com ~all",
"dmarc": "v=DMARC1; p=reject; rua=mailto:[redacted]@example.com",
"dmarcPolicy": "reject",
"nxdomain": false,
"dnsErrors": 0
}
  • emailProvider is one of google_workspace, microsoft_365, proofpoint, mimecast, zoho, godaddy, fastmail, proton, mailgun, amazon_ses, yandex, other, or none (no MX).
  • resolver is cloudflare, google, or mixed.
  • Mailbox names in TXT, DMARC and CAA records are redacted ([redacted]@domain), and soa.rname is always null. These can identify people, so they are not output.

Error row (recordType: "error", free): {recordType, input, domain, errorCode, message, scrapedAt}. It is used for input that is not a valid domain (INVALID_DOMAIN), such as IP addresses, localhost, illegal characters or labels that are too long.

Pricing

Pay per event, with no extra platform usage fees:

EventWhenFREEBRONZESILVERGOLDPLATINUMDIAMOND
domainDomain looked up (registered or not found)$0.0020$0.0018$0.0015$0.0012$0.0012$0.0012
dns-recordsDNS records + email/SPF/DMARC add-on (per domain whose DNS lookup completed)$0.0010$0.0009$0.0008$0.0006$0.0006$0.0006
change-detectedMonitor mode: domain changed$0.0050$0.0050$0.0040$0.0035$0.0035$0.0035
apify-actor-startActor start$0.002$0.002$0.002$0.002$0.002$0.002
  • Free: unsupported_tld and error rows, and invalid input rows.
  • 10,000 domains = $20 on the Free tier; with DNS = $30.
  • Filters only charge matching rows. With expiringWithinDays or onlyAvailable, rows that are filtered out are neither output nor charged.
  • Monitor mode: In monitor mode you pay per domain checked, plus a small fee per detected change. Unchanged domains are not output but are charged domain, because the check itself is the service. New and changed domains are output.
  • Set Max cost per run to cap spending. The run stops cleanly with "Stopped: max cost per run reached after N domains".

Use as an MCP tool / AI agents

  • MCP server URL: https://mcp.apify.com/?tools=OptimistPrime/domain-rdap-whois-dns
  • Minimal call: {"domains":["example.com"]} returns one small typed row.
  • Is it available? Check registrationStatus and likelyAvailable.
  • When does it expire? Check expiresAt and daysUntilExpiry.
  • Who is the registrar? Check registrar and registrarIanaId.
  • Which email provider? Call with includeDns: true and read dns.emailProvider. Also see dns.spf and dns.dmarcPolicy.
  • Dates are ISO UTC and day counts are integers, so no string math is needed.

TLD coverage

  • Generic TLDs: every gTLD in the IANA RDAP bootstrap (.com, .net, .org, .dev, .app, .xyz, .info, .shop, …), i.e. all gTLDs in the root zone except the restricted .edu, .mil and the infrastructure TLD .arpa.
  • Country-code TLDs: the 76 ccTLDs in the bootstrap (e.g. .uk, .fr, .nl, .pl, .br, .ca, .au, .in, .no, .fi, .cz, .tv, .cc), plus the verified extra servers for .io, .me, .de and .us.
  • The bootstrap is fetched fresh at the start of every run, so a registry that launches RDAP is picked up automatically. If IANA is unreachable, a bundled copy is used.
  • Domains on any other TLD are returned as unsupported_tld, free of charge, with DNS data if you asked for it (includeDns: true).

TLDs with no public RDAP service

Source: the IANA root zone list (version 2026100300) compared with the IANA RDAP bootstrap (published 2026-09-30) on 2026-10-03, minus the four verified extra servers above. These TLDs are listed in the root zone but have no RDAP server in the bootstrap, so the Actor returns them as unsupported_tld (free). The list changes as registries add RDAP.

Common ones (all seen in our 1,000-domain Tranco top-list test): .ru, .edu, .cn, .co, .it, .jp, .eu, .es, .be, .ee, .gg, .gl, .hk, .nz, .sh, .za, .mp, .arpa.

Other widely used ones: .ch, .li, .at, .se, .dk, .ie, .pt, .gr, .hu, .ro, .sk, .lt, .lv, .il, .tr, .ae, .sa, .mx, .cl, .pe, .ve, .my, .ph, .vn, .pk, .kz, .by, .su, .mil.

Second-level domains such as .co.uk follow their TLD (.uk is supported). The 2026-10-03 test on the Tranco top 1,000 domains returned 911 registered rows and 89 free unsupported_tld rows (all on TLDs in the list above), with 0 errors. Every domain on a supported TLD was found.

Acceptable use and data source terms

This Actor only uses public, official protocols: registry RDAP services and public DNS-over-HTTPS resolvers. It applies polite rate limits: 5 requests/s per registry, slowing down automatically on HTTP 429.

Each registry's terms apply to the data it returns. registryTermsUrl links them where the registry publishes a link, for example Verisign. Common rules across registries:

  • No spam. Don't use this data for unsolicited commercial email, telemarketing, mass unsolicited outreach or targeted advertising.
  • No abusive high-volume querying. Don't use it to harass, or to build a contact or marketing database.
  • DENIC (.de) allows use only for technical or administrative needs of Internet operation, or to resolve legal problems. Do not use .de data for advertising or marketing.

You are responsible for using the results in line with these terms and applicable law, including GDPR and anti-spam law.

FAQ

How does this compare with other WHOIS / domain lookup Actors? Comparable Store Actors cost $0.0023–$0.003 per domain, some with a per-run start fee of up to $0.035. This Actor is $0.002 per domain with official RDAP data, expiry/availability filters, SPF/DMARC and change monitoring.

Why no registrant name or email? Since GDPR, most registries redact contact data anyway. Where it is still published, contact data is personal data. This Actor removes every registrant, admin, tech, billing and abuse contact, including from rawRdap. It only keeps the registrar's name, URL and IANA ID. It also does not follow registrar RDAP referrals, which mainly contain contact data.

Is "likely available" guaranteed? No. likelyAvailable: true means the registry has no record of the domain and DNS returns NXDOMAIN, so the domain is likely available. Premium or reserved names may still be unavailable. Always confirm with a registrar before you rely on it.

Why are .de dates missing? DENIC does not publish creation or expiry dates in RDAP. For .de, createdAt, expiresAt, ageDays and daysUntilExpiry are null. This also means .de domains are excluded when expiringWithinDays is greater than 0.

Why is a domain error? The registry failed or rate-limited the lookup after 4 retries. See errorMessage. Error rows are free, so just run those domains again.

Changelog and support

See the ./CHANGELOG.md. Report problems or requests in the Issues tab.