Domain Intelligence API — DNS, RDAP & SSL avatar

Domain Intelligence API — DNS, RDAP & SSL

Pricing

from $0.90 / 1,000 domain analyseds

Go to Apify Store
Domain Intelligence API — DNS, RDAP & SSL

Domain Intelligence API — DNS, RDAP & SSL

Turn a list of domains into data. One row each: A, AAAA, MX, NS and TXT records, registrar, creation and expiry dates from RDAP, the TLS certificate, SPF and DMARC, plus who runs the email, DNS and hosting. No API key, no WHOIS scraping, no login.

Pricing

from $0.90 / 1,000 domain analyseds

Rating

0.0

(0)

Developer

Insight Solutions

Insight Solutions

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

13 hours ago

Last modified

Share

Domain Intelligence API — DNS, RDAP, SSL & Providers

Everything public about a domain, as one flat row. Give this Actor a list of domains — bare (apify.com), with www., as full URLs, or as email addresses — and get back, per domain: every DNS record that matters, the registrar and the registration and expiry dates from RDAP, the TLS certificate the host presents, what answers on the web, and the names of the companies behind it all: who runs their email, who runs their DNS, who hosts them, and which SaaS tools they have verified their domain with.

No API key. No WHOIS rate limits. No login. $1.50 per 1,000 domains, proxy included — domains that do not exist are free, and a run that returns nothing costs nothing at all.

Try it in 30 seconds

{
"domains": ["apify.com", "notion.so", "bbc.co.uk", "stripe.com"],
"dns": true,
"rdap": true,
"ssl": true,
"http": true
}

Four domains, four rows. Turn a source off and its columns come back null and its requests are never made — {"http": false} is the cheapest and fastest configuration and still gives you DNS, registration and the certificate.

What comes back

One domain row per domain:

{
"ok": true,
"rowType": "domain", // "domain" | "diagnostic"
"input": "apify.com", // exactly what you sent
"domain": "apify.com", // the registrable domain everything is about
"tld": "com",
// --- registration (RDAP) ---
"registered": true,
"registrar": "Amazon Registrar, Inc.",
"registrarIanaId": "468",
"abuseEmail": "trustandsafety@support.aws.com",
"registeredAt": "2009-06-02T17:14:10.000Z",
"updatedAt": "2026-05-16T16:53:04.000Z",
"expiresAt": "2035-06-02T17:14:10.000Z",
"domainAgeDays": 6309,
"expiresInDays": 3186,
"registrationStatus": ["client transfer prohibited"],
"registrationNote": null, // "no RDAP service for this TLD" when nobody could say
"dnssec": true,
// --- DNS ---
"nameservers": ["ns-1225.awsdns-25.org", "ns-1928.awsdns-49.co.uk", "ns-839.awsdns-40.net", "ns-449.awsdns-56.com"],
"dnsProvider": "Amazon Route 53",
"ipAddresses": ["143.204.204.87", "143.204.204.97", "143.204.204.42", "143.204.204.5"],
"ipv6Addresses": null,
"cname": null,
// --- email ---
"mxRecords": [{ "priority": 1, "host": "aspmx.l.google.com" }, { "priority": 5, "host": "alt1.aspmx.l.google.com" }],
"emailProvider": "Google Workspace",
"acceptsEmail": true,
"spf": "v=spf1 a mx include:_spf.google.com include:mailgun.org include:amazonses.com -all",
"spfIncludes": ["_spf.google.com", "mailgun.org", "amazonses.com"], // the services they send through
"dmarc": "v=DMARC1; p=reject; sp=reject; pct=100; rua=mailto:dmarc-reports@apify.com; ri=604800",
"dmarcPolicy": "reject",
"hasDkimHint": false, // a hint only — see Limits
"txtRecords": ["…all eleven of them…"],
"verifications": ["Google", "Tito", "Zapier", "OpenAI", "Mixpanel"], // tools they have connected
"hasMcp": true, // a v=MCPv1 record at the apex
"mcpRecord": "v=MCPv1; k=ed25519; p=1rDnoEigwTr+4JjG89+sLbdNnswCnLjmaeT34srW53Y=",
// --- TLS ---
"ssl": {
"subject": "apify.com",
"sans": ["apify.com", "*.apify.com"],
"issuer": "Amazon — Amazon RSA 2048 M02",
"validFrom": "2026-08-12T00:00:00.000Z",
"validTo": "2027-09-11T23:59:59.000Z",
"daysUntilExpiry": 365,
"valid": true, // false + an error is a finding, not a failure
"error": null,
"protocol": "TLSv1.3",
"serialNumber": "0AF1B2C3…",
"fingerprint256": "A1:B2:C3:…"
},
"sslError": null,
// --- the website ---
"http": {
"requestedUrl": "https://basecamp.com/", // shown for a domain that redirects
"finalUrl": "https://www.basecamp.com/",
"status": 200,
"redirected": true,
"redirects": ["https://basecamp.com/", "https://www.basecamp.com/"],
"server": "cloudflare",
"hsts": false,
"title": "Basecamp — Pricing", // the page <title>, and nothing else from the body
"wwwCanonical": true,
"scheme": "https"
},
"hostingHint": "Cloudflare", // modest on purpose — see Limits
"partial": false,
"sources": { "dns": true, "rdap": true, "ssl": true, "http": true },
"checkedAt": "2026-09-11T16:00:00.000Z",
"error": null,
"errorType": null,
"scrapedAt": "2026-09-11T16:00:00.000Z",
"source": "dns+rdap+ssl+http",
"sourceUrl": "https://rdap.org/domain/apify.com"
}

Every row carries the same columns, so live domains, parked domains and entries that were never domains export as one rectangular table. (The http and ssl blocks above are shown from a different domain, so that a redirect and a certificate are both visible in one place.)

Use cases

  • CRM and lead enrichment. Paste the domain column out of your CRM and get back company age, mail provider, DNS provider and the SaaS tools each company has verified. registeredAt dates a company better than most databases do.
  • Technographic segmentation. emailProvider splits a list into Google Workspace and Microsoft 365 shops in one pass. verifications and spfIncludes name the tools they already pay for — a company with include:mailgun.org has a developer sending transactional mail.
  • Domain portfolio monitoring. expiresInDays, registrationStatus and ssl.daysUntilExpiry on a weekly schedule is an expiry alarm for a whole portfolio, registrar-independent.
  • Security and deliverability audits. dmarcPolicy, spf, dnssec and ssl.valid across a customer list, an acquisition target or your own estate. A domain with p=none and no SPF is spoofable today.
  • Brand protection and typosquat triage. Feed a list of lookalike domains: registered, registeredAt, nameservers and http.title tell you in one row which are parked, which are new, and which are serving a page.
  • M&A and competitive research. registeredAt, hostingHint, dnsProvider and the certificate's sans sketch an infrastructure footprint without touching anything private. Certificate SANs in particular often name sibling brands.
  • Data cleaning. registered: false and the not-found diagnostic separate real domains from typos and dead ones before you spend money on the rest of your pipeline.

How it works, and why it keeps working

There is no single "domain API", because a domain is not one thing: the registration belongs to a registry, the records belong to whoever runs the DNS, the certificate belongs to the host, and the website is a fourth party again. This Actor reads all four and merges them.

SourceWhat it readsRequests
DNS over HTTPSdns.google/resolve, falling back to cloudflare-dns.com/dns-query — A, AAAA, MX, NS, TXT, CNAME, SOA, and _dmarc.<domain> TXT8, sent together
RDAPrdap.org/domain/<domain>, which redirects to the domain's own registry (Verisign for .com, Nominet for .uk, and so on)1
TLSA direct socket to port 443. The certificate is read off the handshake; no HTTP request is sent0 HTTP, 1 handshake
HTTP head checkOne GET https://<domain>/, falling back to http://. The body is read for its <title> and nothing else1

Ten requests and one handshake per domain, and about 7 KB of it is everything except the head check.

No source may fail the row. They are run by different organisations and fail for unrelated reasons — a TLD with no RDAP server, a host that closes port 443, a website that has not existed for two years. Each one degrades to nulls, sources records which answered, and partial says out loud that something is missing. Only a domain where nothing at all answered becomes a free diagnostic row.

The order is not arbitrary. DNS goes first because it is the cheapest way to find out whether the name exists. If DNS says NXDOMAIN, the socket work is skipped — there is no address to connect to — but RDAP is still asked, because a registered domain with no delegation is exactly the state somebody watching a portfolio wants to see. RDAP, TLS and the head check then run together.

Two 404s that mean opposite things. rdap.org answers 404 both when it has no server for a TLD (.io, .de and others) and when a registry genuinely has no such domain. The first is registered: null with registrationNote: "no RDAP service for this TLD"; the second is registered: false. Conflating them would report live businesses as unregistered domains, and a surprising number of tools do.

How it compares

This ActorA WHOIS APIA DNS lookup toolDoing it yourself
DNS, registration, TLS and HTTP in one rowYesNoNoFour integrations
Email / DNS / hosting provider namedYesNoNoYour own lookup tables
TLDs with no RDAP server handled honestlyregistered: null + a noteOften "available"n/aEasy to get wrong
Expired certificateReported in fulln/aOften refusedrejectUnauthorized: false
Cost per 1,000 domains$1.50$5–$20, often per sourceVariesRate limits and a maintenance job

Input reference

FieldTypeDefaultWhat it does
domainsarrayDomains, www. hosts, full URLs or email addresses, mixed freely. Everything reduces to the registrable domain and duplicates are looked up once
dnsbooleantrueThe eight DNS lookups. Source of the providers, SPF, DMARC, verifications and addresses
rdapbooleantrueRegistrar, dates, status, DNSSEC
sslbooleantrueThe TLS certificate, read from a direct socket
httpbooleantrueOne request to the website: final URL, status, server, HSTS, title. This is the only expensive request
maxConcurrencyinteger3Domains in parallel. Held at 3 by RDAP's rate limit; raise it if you switch rdap off
maxRunSecsinteger240Wall-clock budget. Rows already written are kept and billed; domains never reached get free diagnostic rows
proxyConfigurationobjectApify datacenterDatacenter is right for every source here. The TLS check never uses it

Output reference

ColumnOnMeaning
ok, rowType, input, domain, tldallIdentity. rowType is domain or diagnostic
registered, registrar, registrarIanaId, abuseEmaildomainWho sponsors the registration. registered: null means nobody could say
registeredAt, updatedAt, expiresAt, domainAgeDays, expiresInDaysdomainThe registration timeline, in UTC
registrationStatus, registrationNote, dnssecdomainEPP status codes, why registration is missing, whether the delegation is signed
nameservers, dnsProviderdomainLive NS records, and the operator recognised from them
ipAddresses, ipv6Addresses, cnamedomainA, AAAA, and the alias target when there is one
mxRecords, emailProvider, acceptsEmaildomainMail exchangers by priority, and who runs them
spf, spfIncludes, dmarc, dmarcPolicy, hasDkimHintdomainThe email authentication posture
txtRecords, verifications, hasMcp, mcpRecorddomainEvery apex TXT record, the vendors they name, and any MCP declaration
ssl, sslErrordomainThe certificate, or why there is none
http, hostingHintdomainWhat answered on the web, and a modest guess at who serves it
partial, sources, checkedAtdomainWhich sources answered, and when
error, errorTypediagnosticWhat went wrong, and a type to branch on
scrapedAt, source, sourceUrlallWhen the row was written, and where it came from

errorType is one of not-found, invalid-input, blocked, timeout, unavailable.

Pricing

$1.50 per 1,000 domains. Pay-per-event, with proxy already inside that number — there is no separate proxy line on your bill for this Actor.

EventWhat triggers itFREEStarterScaleBusiness
Domain analysed (primary)One domain row written to your dataset$0.0015$0.0015$0.0012$0.0009
Run startedOnce per run, after the first paid row$0.001$0.001$0.001$0.001

One event, not four, because you do not choose which sources will answer. A .de domain has no RDAP server; a parked domain has no certificate. A row is a row — and partial and sources tell you exactly what was and was not available.

Worked example. 500 domains out of a CRM export, of which 12 are typos, 3 are dead, and 40 are on TLDs with no RDAP server:

  • 485 domain rows × $0.0015 = $0.7275 (the 40 without registration data are rows like any other)
  • 1 run start = $0.001
  • 12 typos + 3 dead domains = $0.00 (free diagnostic rows)
  • Total: $0.7285

Portfolio monitoring example. 200 owned domains, weekly, http: false: 200 × $0.0015 + $0.001 = $0.301 a run, about $1.30 a month.

Single lookup. One domain: $0.0015 + $0.001 = $0.0025.

What you are never charged for: a domain that does not exist, an entry that was not a domain, a domain every source refused, or a domain the run never reached before maxRunSecs. If a whole run comes back empty it finishes FAILED and bills nothing at all, start fee included.

Set ACTOR_MAX_TOTAL_CHARGE_USD on a run and the Actor stops looking domains up once the ceiling is in sight, rather than handing you rows it cannot bill or billing you for rows it cannot hand over. It finishes SUCCEEDED with the ceiling named in its status message, and everything already delivered is yours.

Limits, and the ones that might bite

Some TLDs have no RDAP server, and you get null rather than a guess. .io, .de and a long tail of others publish nothing the bootstrap service can reach. Those rows carry registered: null and registrationNote: "no RDAP service for this TLD" — the DNS, TLS and HTTP columns are complete, and the registration columns are honestly empty. A tool that reports those as available domains is wrong, not thorough.

RDAP redaction is the registry's choice, not ours. ICANN's rules and GDPR mean most registries redact the registrant entirely — Nominet publishes redacted@nominet.uk in place of an address. There is no registrant name, address or email in these rows for most TLDs, because there is none in the source. abuseEmail is the registrar's published reporting address, which is a different thing.

hasDkimHint is a hint. A DKIM key lives at <selector>._domainkey.<domain>, and the selector is a string the sender chose — there is no way to enumerate it without guessing a dozen names per domain. false here means nothing at the apex mentions DKIM; it does not mean the domain does not sign its mail.

hostingHint is deliberately modest. It comes from the server header, then the CNAME, then the nameservers, and it is null whenever nothing identifies itself — nginx names software, not a host. Reverse-mapping IP ranges to cloud providers is out of scope: it is a large, stale dataset and it would make this column look more certain than it is.

The redirect chain records endpoints, not every hop. http.redirects holds the address asked for and the address that answered. The individual 301s in between are followed by the HTTP client and are not exposed. finalUrl, wwwCanonical and scheme are what the chain was for, and they are exact.

The head check reads the <title> and nothing else. This is not a page audit. If you want headings, meta tags, structured data, links or a technology fingerprint, that is a different job — see Website Tech Detector.

DNS answers come from a public resolver's cache. Google and Cloudflare answer from cache, so a record changed in the last few minutes may not be visible yet. checkedAt is the freshness of the row, not of the records; TTLs on most of these are 300–3,600 seconds.

One domain per row, and subdomains reduce to it. mail.example.com is looked up as example.com, because that is the unit RDAP, SOA and NS all agree on. The hostname you typed is still what the TLS and HTTP checks connect to, so www. behaves the way you meant.

The upstream format may change. Resolvers, registries and the RDAP bootstrap change their output without notice — that is true of every tool that reads this data, including the ones that do not say so. When a shape changes you get nulls and free diagnostic rows rather than quietly wrong data, and a run that returns nothing bills nothing.

Rate and reliability. RDAP's bootstrap service rate-limits at a few requests a second; a 429 is waited out and retried once rather than retried from a different address, because hammering a public good from a second IP is worse behaviour, not better. That is why maxConcurrency defaults to 3.

Use it from an AI agent, or from code

One JSON object in, one flat array out — the shape agent runtimes want. The Actor runs with limited permissions, uses pay-per-event pricing and never enters Standby, so it works over the Apify MCP server and with x402 agentic payments. The Integrations tab pushes results to Slack, a webhook, Zapier, Make, Google Sheets, Snowflake or BigQuery.

curl -X POST "https://api.apify.com/v2/acts/insight.solutions~domain-intelligence-api/run-sync-get-dataset-items?token=$APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{"domains":["apify.com","bbc.co.uk"],"http":false}'
# pip install apify-client
from apify_client import ApifyClient
client = ApifyClient("<APIFY_TOKEN>")
run = client.actor("insight.solutions/domain-intelligence-api").call(run_input={
"domains": ["apify.com", "notion.so", "sales@stripe.com"],
"dns": True,
"rdap": True,
"ssl": True,
"http": False,
})
for row in client.dataset(run["defaultDatasetId"]).iterate_items():
if row["rowType"] != "domain":
continue
print(row["domain"], row["emailProvider"], row["dnsProvider"], row["expiresInDays"])

FAQ

Do I need a WHOIS account or an API key? No. Every source here is public: two public DNS resolvers, the RDAP bootstrap service that ICANN requires registries to run, a TLS handshake, and one ordinary web request.

Is this WHOIS? It is RDAP, which is WHOIS's structured, ICANN-mandated replacement: JSON instead of free text, and the same data the registry would serve over port 43. It is parsed rather than regex-scraped, which is why the dates are reliable.

Why is registered null for my .io domain? Because no RDAP server exists for that TLD, so nothing authoritative could be asked. registrationNote says so on the row. The DNS, TLS and HTTP columns for that domain are complete.

Can I check just DNS, or just the certificate? Yes — each of the four sources is a switch. {"http": false} is the big one: it removes the only request that moves real bytes, and makes a large run both faster and cheaper.

How do I deduplicate between runs? On domain, which is the registrable domain and is stable however the entry was spelled. An incremental pipeline is an upsert keyed on it.

What happens if one domain fails? The others still run. The failed one produces a free diagnostic row and the run finishes SUCCEEDED. If every entry fails, the run finishes FAILED and you are billed nothing at all.

Why does a domain have partial: true? At least one source you asked for did not answer — usually RDAP on a TLD without a server, or the TLS and HTTP checks on a domain with no addresses. sources names which.

Does an invalid certificate break the row? No, it is the point. The handshake completes without verification, and ssl.valid: false with ssl.error tells you which check failed — expired, self-signed, wrong hostname — while the certificate itself is reported in full.

How fresh is the data? Live, subject to DNS caching. Every run asks the resolvers, the registry and the host at that moment; nothing is cached inside the Actor beyond one RDAP answer per domain per run.

Can I look up a subdomain? Send it and the registration and DNS columns will be about its registrable domain, while the TLS and HTTP checks connect to the host you typed. For records on the subdomain specifically, that is a different query shape than this Actor's row.

  • Public infrastructure only. DNS over HTTPS, the ICANN-mandated RDAP service, a TLS handshake and a single unauthenticated GET. The Actor never logs in, never sends cookies or session tokens, and never takes an API key belonging to anyone else.
  • RDAP data is published by registries under ICANN policy, already redacted at source. Where a contact address does survive — a registrar's abuse mailbox, a company that registered in its own name — it is still personal data in many jurisdictions when it identifies a person. Have a lawful basis before using it for outreach, honour opt-outs, and check the marketing rules where you and the recipient are.
  • abuseEmail is for reporting abuse. It is published so that network operators can report phishing and spam. Using it for sales outreach is a misuse of a public safety mechanism and registrars treat it as such.
  • Certificate contents are public by design. Certificates are presented to every client that connects and are also logged to public Certificate Transparency logs.
  • Not affiliated with ICANN, any registry, registrar, DNS provider, certificate authority or hosting company named in the output. All names and trademarks belong to their owners and are used only to describe which public records were read.

Our other Actors

Every Insight Solutions Actor is pay-per-result with no browser, no login and no API key, and every one of them returns free diagnostic rows instead of billing for failures. Prices are per 1,000 results.

Video, audio & social

News, documents & the web

Business, finance & jobs

Apps & games