Echo Lab Tools

Echo Lab Tools › Domain & SSL expiry

Check domain expiry dates and SSL certificates for thousands of domains in one run

The bulk domain expiry checker is an Apify Actor that takes up to 5,000 domains or URLs and returns one JSON row per host with the domain expiration date and days left (from RDAP), the registrar, SSL certificate validity and days left, DNS records, SPF/DMARC status, and short warning codes such as domain_expires_soon.

What you get

  • Domain expiration date, days left, registrar, status and nameservers via RDAP (the registry-run successor to WHOIS)
  • SSL certificate check on port 443: valid or not, issuer, SANs, expiry date, days left, TLS version
  • DNS records (A, AAAA, MX, NS, TXT, CAA) plus SPF and DMARC policy, with alert-ready warning codes

Price: $1.50 per 1,000 domains + $0.00005 per runLogin needed: noRuns on: Apify (API, schedule, MCP)

Run the bulk domain checker on Apify →See real output ↓

How it works

Paste bare domains or full URLs. The Actor lowercases them, strips scheme, path and port, converts international names to IDNA and removes duplicates, so a messy spreadsheet column works as input. Invalid lines are skipped and not billed. Then, for each unique host, it runs four checks you can switch on or off:

Each row ends with a status (ok, warning or error) and a warnings list, so a scheduled run can feed Slack, email or a webhook with only the domains that need attention.

Sample output

One row from a real run on the Apify platform (run 3F0eyt2dnY0DSbwrh, build 0.1.6, 2026-11-05) with RDAP and SSL turned on:

{
  "registrar": "MarkMonitor Inc.",
  "registrationDate": "2007-10-09T18:20:50Z",
  "expirationDate": "2028-10-09T18:20:50Z",
  "lastChangedDate": "2026-09-07T09:22:52Z",
  "daysUntilDomainExpiry": 703,
  "domainStatus": [
    "client delete prohibited",
    "client transfer prohibited",
    "client update prohibited"
  ],
  "nameservers": [
    "dns1.p08.nsone.net",
    "dns2.p08.nsone.net",
    "dns3.p08.nsone.net",
    "dns4.p08.nsone.net",
    "ns-1283.awsdns-32.org",
    "ns-1707.awsdns-21.co.uk",
    "… 2 more"
  ],
  "dnssecSigned": false,
  "rdapError": null,
  "sslValid": true,
  "sslError": null,
  "sslIssuer": "Sectigo Limited, Sectigo Public Server Authentication CA DV E36",
  "sslSubject": "github.com",
  "sslSans": [
    "github.com",
    "www.github.com"
  ],
  "sslNotBefore": "2026-10-30T00:00:00Z",
  "sslNotAfter": "2027-01-27T23:59:59Z",
  "daysUntilSslExpiry": 83,
  "sslTlsVersion": "TLSv1.3",
  "dns": null,
  "hasSpf": null,
  "spfRecord": null,
  "hasDmarc": null,
  "dmarcPolicy": null,
  "dmarcRecord": null,
  "domain": "github.com",
  "inputValue": "github.com",
  "checkedAt": "2026-11-05T19:07:12.921734Z",
  "warnings": [],
  "status": "ok"
}

The same run included expired.badssl.com, a test host with a deliberately expired certificate. It came back with sslValid: false, sslNotAfter: "2015-04-12T23:59:59Z", daysUntilSslExpiry: -4225 and warnings: ["ssl_expired","ssl_invalid"].

Expiry dates from a second real run (128Ws8GLBaRlo3XKb) across gTLDs and ccTLDs, including .io and .so, which are not in the IANA RDAP list and need the registry fallback:

Domain Registrar (from RDAP) Expires Days left on run day
github.com MarkMonitor Inc. 2028-10-09 703
wikipedia.org MarkMonitor Inc. 2027-01-13 67
bbc.co.uk British Broadcasting Corporation 2034-12-13 2958
lemonde.fr NAMESHIELD 2027-06-09 215
notion.so 1API 2027-03-31 144
web.dev MarkMonitor Inc. 2027-10-29 357
nic.io Registry Operator acts as Registrar (9999) 2027-05-01 175
cira.ca CIRA Default Registrar 2050-02-05 8492

And SPF/DMARC from a third run (ubddcWcK1ELriXsAO):

Domain SPF DMARC Warnings
google.com yes yes, p=reject none
github.com yes yes, p=quarantine none
heise.de yes yes, p=none dmarc_policy_none
python.net no no no_mx no_spf no_dmarc

Output fields

Field Type Example Meaning
domain, inputValue string github.com Normalized host and the first original input
registrar string / null MarkMonitor Inc. Registrar company only, never contact details
expirationDate, daysUntilDomainExpiry string / integer 2028-10-09…, 703 RDAP expiry and whole days left
domainStatus, nameservers, dnssecSigned array / boolean client transfer prohibited Registry status and delegation
rdapError string / null no_rdap_server Why registration data is missing
sslValid, sslError boolean / string true Chain and hostname verified; null if the connection failed
sslIssuer, sslSans, sslNotAfter, daysUntilSslExpiry, sslTlsVersion mixed TLSv1.3 Certificate details
dns object {"MX": [...]} Record type → answers
hasSpf, hasDmarc, dmarcPolicy boolean / string reject Email authentication records
warnings, status array / string ["ssl_expired"] Alert codes and overall status

How much does a bulk domain check cost?

Pricing is per result: $1.50 per 1,000 domains ($0.0015 per unique host) plus $0.00005 per run, with Apify platform usage included. Duplicates and invalid lines are not billed.

Worked examples: an agency checking 50 client domains every day pays 50 × $0.0015 ≈ $0.075 per run, about $2.25 per month. A one-off audit of 1,000 domains is $1.50; the maximum batch of 5,000 is $7.50. Apify's free plan includes $5 a month for Store tools (apify.com/pricing, checked 2026-11-06), enough for about 3,300 checks.

Limits you should know about

  1. Some ccTLDs have no public RDAP. In November 2026 we found none for .de, .jp, .cn, .ru, .eu, .ch, .it, .es, .se, .dk, .at, .be, .us or .edu. Those rows get rdapError: no_rdap_server and status: error; SSL, DNS and email checks still run. There is no WHOIS fallback.
  2. Some registries answer without an expiry date (for example .nl, .au, .pl). You get the domain_expiry_unknown warning instead of a silent "ok".
  3. RDAP expiry is the registry date. It can differ from the renewal date your registrar shows, for example around auto-renewal and grace periods.
  4. SSL is checked on port 443 of the host you give. Other ports and other hostnames on the same server are not scanned; a network failure leaves sslValid null.
  5. SPF/DMARC checks detect records and the DMARC policy. They do not expand SPF includes, count DNS lookups or test real mail delivery.

API: call it from code

curl -X POST "https://api.apify.com/v2/acts/echolab~domain-health-monitor/run-sync-get-dataset-items" \
  -H "Authorization: Bearer $APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"domains": ["example.com", "https://www.example.org/page"], "expiryWarningDays": 30}'

Python, keeping only the rows that need attention:

from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")
domains = [line.strip() for line in open("domains.txt") if line.strip()]
run = client.actor("echolab/domain-health-monitor").call(run_input={
    "domains": domains,          # up to 5,000
    "expiryWarningDays": 30,
})
for row in client.dataset(run["defaultDatasetId"]).iterate_items():
    if row["warnings"]:
        print(row["domain"], row["daysUntilDomainExpiry"], row["daysUntilSslExpiry"], row["warnings"])

Bulk domain checker vs. alternatives

Option Good for Trade-off
This Actor One table for expiry, SSL, DNS and SPF/DMARC across hundreds or thousands of domains; daily schedules No WHOIS fallback for ccTLDs without RDAP; not an uptime monitor
Your own whois + openssl s_client script Free, a handful of domains WHOIS text differs per registry and is rate-limited; you parse and maintain it
Uptime/SSL monitoring services Minute-level uptime checks and alert routing Usually priced per monitor; registration expiry is often missing or a paid extra
Commercial WHOIS APIs Historical WHOIS, ownership research, wider ccTLD coverage Per-query or subscription pricing; SSL/DNS/email checks are separate products

When not to use it: if most of your domains are .de or .jp, registration expiry will be missing, so use your registrar's export instead. If you need to know within a minute that a site is down, use an uptime monitor. This tool is for a scheduled renewal-and-certificate audit of many domains in one dataset.

FAQ

Is this a WHOIS lookup? It uses RDAP, the registry-run successor to WHOIS. Registrant contact details are never output, only the registrar company.

Can it alert me before something expires? Schedule it daily and filter rows whose warnings contain domain_expires_soon, ssl_expires_soon, domain_expired or ssl_expired; expiryWarningDays sets the window.

Open the bulk domain checker on Apify for the full input schema.

Changelog

  • 2026-11-06 — build 0.1.7: registry RDAP fallback for .io, .co, .me, .so, .sh, .ac, .ag, .bz, .lc, .mn, .vc and .gi (missing from the IANA list); new domain_expiry_unknown warning for registries that publish no expiry date; unregistered domains now report domain_not_found.
  • 2026-11-04 — switched to pay-per-result pricing ($1.50 per 1,000 domains).
  • 2026-11-04 — first public release on the Apify Store.

Run the bulk domain checker on Apify →