# Domain Intelligence API — DNS, RDAP & SSL (`insight.solutions/domain-intelligence-api`) Actor

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.

- **URL**: https://apify.com/insight.solutions/domain-intelligence-api.md
- **Developed by:** [Insight Solutions](https://apify.com/insight.solutions) (community)
- **Categories:** Developer tools, Lead generation, SEO tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.90 / 1,000 domain analyseds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## 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

```json
{
  "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:

```jsonc
{
  "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.

| Source | What it reads | Requests |
|---|---|---|
| **DNS over HTTPS** | `dns.google/resolve`, falling back to `cloudflare-dns.com/dns-query` — A, AAAA, MX, NS, TXT, CNAME, SOA, and `_dmarc.<domain>` TXT | 8, sent together |
| **RDAP** | `rdap.org/domain/<domain>`, which redirects to the domain's own registry (Verisign for `.com`, Nominet for `.uk`, and so on) | 1 |
| **TLS** | A direct socket to port 443. The certificate is read off the handshake; no HTTP request is sent | 0 HTTP, 1 handshake |
| **HTTP head check** | One `GET https://<domain>/`, falling back to `http://`. The body is read for its `<title>` and nothing else | 1 |

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 Actor | A WHOIS API | A DNS lookup tool | Doing it yourself |
|---|---|---|---|---|
| DNS, registration, TLS and HTTP in one row | Yes | No | No | Four integrations |
| Email / DNS / hosting provider named | Yes | No | No | Your own lookup tables |
| TLDs with no RDAP server handled honestly | `registered: null` + a note | Often "available" | n/a | Easy to get wrong |
| Expired certificate | Reported in full | n/a | Often refused | `rejectUnauthorized: false` |
| Cost per 1,000 domains | $1.50 | $5–$20, often per source | Varies | Rate limits and a maintenance job |

### Input reference

| Field | Type | Default | What it does |
|---|---|---|---|
| `domains` | array | — | Domains, `www.` hosts, full URLs or email addresses, mixed freely. Everything reduces to the registrable domain and duplicates are looked up once |
| `dns` | boolean | `true` | The eight DNS lookups. Source of the providers, SPF, DMARC, verifications and addresses |
| `rdap` | boolean | `true` | Registrar, dates, status, DNSSEC |
| `ssl` | boolean | `true` | The TLS certificate, read from a direct socket |
| `http` | boolean | `true` | One request to the website: final URL, status, `server`, HSTS, title. **This is the only expensive request** |
| `maxConcurrency` | integer | `3` | Domains in parallel. Held at 3 by RDAP's rate limit; raise it if you switch `rdap` off |
| `maxRunSecs` | integer | `240` | Wall-clock budget. Rows already written are kept and billed; domains never reached get free diagnostic rows |
| `proxyConfiguration` | object | Apify datacenter | Datacenter is right for every source here. The TLS check never uses it |

### Output reference

| Column | On | Meaning |
|---|---|---|
| `ok`, `rowType`, `input`, `domain`, `tld` | all | Identity. `rowType` is `domain` or `diagnostic` |
| `registered`, `registrar`, `registrarIanaId`, `abuseEmail` | domain | Who sponsors the registration. `registered: null` means nobody could say |
| `registeredAt`, `updatedAt`, `expiresAt`, `domainAgeDays`, `expiresInDays` | domain | The registration timeline, in UTC |
| `registrationStatus`, `registrationNote`, `dnssec` | domain | EPP status codes, why registration is missing, whether the delegation is signed |
| `nameservers`, `dnsProvider` | domain | Live NS records, and the operator recognised from them |
| `ipAddresses`, `ipv6Addresses`, `cname` | domain | A, AAAA, and the alias target when there is one |
| `mxRecords`, `emailProvider`, `acceptsEmail` | domain | Mail exchangers by priority, and who runs them |
| `spf`, `spfIncludes`, `dmarc`, `dmarcPolicy`, `hasDkimHint` | domain | The email authentication posture |
| `txtRecords`, `verifications`, `hasMcp`, `mcpRecord` | domain | Every apex TXT record, the vendors they name, and any MCP declaration |
| `ssl`, `sslError` | domain | The certificate, or why there is none |
| `http`, `hostingHint` | domain | What answered on the web, and a modest guess at who serves it |
| `partial`, `sources`, `checkedAt` | domain | Which sources answered, and when |
| `error`, `errorType` | diagnostic | What went wrong, and a type to branch on |
| `scrapedAt`, `source`, `sourceUrl` | all | When 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.

| Event | What triggers it | FREE | Starter | Scale | Business |
|---|---|---|---|---|---|
| **Domain analysed** *(primary)* | One `domain` row written to your dataset | $0.0015 | $0.0015 | $0.0012 | $0.0009 |
| Run started | Once 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](https://apify.com/insight.solutions/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.

```bash
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}'
```

```python
## 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.

### Legal and data-protection notes

- **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**

- [YouTube Transcript API](https://apify.com/insight.solutions/youtube-transcript-api) — captions as timed segments, text, SRT or VTT, with language fallback and translation.
- [YouTube Comments API](https://apify.com/insight.solutions/youtube-comments-api) — comments and replies with likes, pinned and hearted flags, newest or top sort.
- [YouTube Channel API](https://apify.com/insight.solutions/youtube-channel-api) — a channel's videos, Shorts and live streams, plus YouTube search.
- [Podcast Search, Episodes & Charts API](https://apify.com/insight.solutions/podcast-api) — Apple Podcasts search, charts and full episode feeds.
- [Bluesky Scraper](https://apify.com/insight.solutions/bluesky-scraper) — profiles, posts, followers and follows from the public AT Protocol API.
- [Telegram Channel Scraper](https://apify.com/insight.solutions/telegram-channel-scraper) — posts, views and channel stats from public Telegram channels.
- [Substack Scraper](https://apify.com/insight.solutions/substack-scraper) — posts with full free text, comments and publication profiles.

**News, documents & the web**

- [Google News Search, Topics & Real Article URLs](https://apify.com/insight.solutions/google-news-api) — news search and topic feeds with the publisher's real URL decoded.
- [Website to Markdown — Content Extractor for LLMs & RAG](https://apify.com/insight.solutions/website-content-extractor) — any site as clean Markdown, text and heading-aware chunks.
- [Internet Archive API](https://apify.com/insight.solutions/internet-archive-api) — archive.org search, item metadata, files and reviews.
- [Wayback Machine Toolkit](https://apify.com/insight.solutions/wayback-toolkit) — archived URL inventories, snapshots and text diffs between dates.
- [Website Technology Detector](https://apify.com/insight.solutions/website-tech-detector) — the tech stack behind any site, with the evidence for each detection.
- [SEO Page Audit](https://apify.com/insight.solutions/seo-page-audit) — sitemap crawl with on-page checks, structured data and broken-link reports.
- [Keyword Suggestions API](https://apify.com/insight.solutions/keyword-suggestions-api) — Google, YouTube, Bing, Amazon and eBay autocomplete with alphabet and question expansions.
- [Website Contact Extractor](https://apify.com/insight.solutions/website-contact-extractor) — emails, phone numbers and social profiles from any list of websites.

**Business, finance & jobs**

- [Congress & Insider Trades API](https://apify.com/insight.solutions/congress-insider-trades-api) — STOCK Act periodic transaction reports and SEC Form 4 insider trades in one schema.
- [SEC EDGAR API](https://apify.com/insight.solutions/sec-edgar-api) — filings, XBRL financials and full-text search by ticker or CIK.
- [Y Combinator Companies, Batches & Founders](https://apify.com/insight.solutions/yc-companies-directory) — the YC directory with founders and social links, filterable by batch, industry and hiring status.
- [Career Site Jobs API](https://apify.com/insight.solutions/ats-jobs-api) — jobs straight from Greenhouse, Lever, Ashby, Workable and 10+ other ATS career sites.
- [New Job Postings Monitor](https://apify.com/insight.solutions/job-postings-monitor) — new, closed and changed postings on the career sites you watch.
- [Shopify Products API](https://apify.com/insight.solutions/shopify-products-api) — any Shopify store's catalogue, variants, prices and stock signals.

**Apps & games**

- [App Store & Google Play Reviews API](https://apify.com/insight.solutions/app-reviews-api) — reviews from both stores with ratings, versions and developer replies.
- [App Store Top Charts & App Search API](https://apify.com/insight.solutions/app-charts-api) — Apple top charts by country and genre, plus app search and details.
- [Steam Reviews API](https://apify.com/insight.solutions/steam-reviews-api) — Steam reviews with playtime, helpfulness and game details.
- [Steam Game Data API](https://apify.com/insight.solutions/steam-store-stats-api) — prices, tags, review scores, live player counts and top charts.

# Actor input Schema

## `domains` (type: `array`):

One entry per domain. Four shapes work and they can be mixed: a **bare domain** (`apify.com`), a **host with www** (`www.bbc.co.uk`), a **full URL** (`https://stripe.com/gb/pricing` — the path is ignored), or an **email address** (`sales@acme.com`), which is read as its domain. Everything reduces to the registrable domain, so a list naming one company three ways is looked up — and billed — once. IP addresses and hostnames with no TLD get a free diagnostic row instead of a request.

## `dns` (type: `boolean`):

Look the domain up in public DNS over HTTPS: **A, AAAA, MX, NS, TXT, CNAME, SOA** and the `_dmarc` TXT record — eight lookups, sent together, a few hundred bytes each. This is where `emailProvider`, `dnsProvider`, `spf`, `dmarc`, the verification records and the IP addresses come from, so leaving it on is almost always right. Two resolvers are used: Google first, Cloudflare if Google will not answer.

## `rdap` (type: `boolean`):

Ask the domain's registry who registered it, when, and when it expires — the modern, structured replacement for WHOIS. One request, which the bootstrap service redirects to the right registry. Some TLDs (`.io`, `.de` and others) publish no RDAP server at all; those rows come back with `registrationNote` saying so and **not** with `registered: false`, which would be a different and untrue claim.

## `ssl` (type: `boolean`):

Open a TLS connection to port 443 and read the certificate the host presents: common name, every SAN, issuer, validity dates, days until expiry, protocol, serial and SHA-256 fingerprint. An **expired or mismatched certificate is reported, not refused** — that is the finding. The apex is tried first and `www.` second, and nothing but the handshake happens: no HTTP request is sent on that socket.

## `http` (type: `boolean`):

One request to `https://<domain>/` (falling back to `http://`) to find out what actually answers: the final URL after redirects, the status code, the `server` header, whether HSTS is set, whether `www` is canonical, and the page `<title>`. The body is read for the title and **nothing else** — this is not a page audit, and it is the only request that touches the website itself.

## `maxConcurrency` (type: `integer`):

How many domains are read at once. Each parallel worker keeps its own proxy session, so one refused resolver burns only its own exit IP. The default of 3 is set by RDAP: the public bootstrap service rate-limits at a few requests a second, and going faster earns 429s rather than answers. Raise it only if you have switched RDAP off.

## `maxRunSecs` (type: `integer`):

Wall-clock budget for the whole run. When it is reached the Actor stops looking domains up, keeps and bills for every row it already wrote, and files a free diagnostic row for each domain it never reached. Nothing is charged for work that did not happen.

## `proxyConfiguration` (type: `object`):

The public resolvers, the RDAP bootstrap service and an ordinary home page all answer datacenter addresses, so the default is Apify's datacenter proxy — much cheaper than residential, and the proxy cost is already inside the per-row price. The TLS check never goes through the proxy: a certificate is presented during the handshake, so there is no request for a proxy to carry.

## Actor input object example

```json
{
  "domains": [
    "apify.com",
    "www.bbc.co.uk",
    "https://stripe.com/gb/pricing",
    "sales@acme.com"
  ],
  "dns": true,
  "rdap": true,
  "ssl": true,
  "http": true,
  "maxConcurrency": 3,
  "maxRunSecs": 240,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `results` (type: `string`):

One row per domain — DNS records, registrar and expiry from RDAP, the TLS certificate, the HTTP head check, and the email, DNS and hosting providers behind them. Domains that could not be read get a free diagnostic row saying why. Delivered as JSON items in the default dataset.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "domains": [
        "apify.com",
        "notion.so",
        "bbc.co.uk",
        "stripe.com",
        "example.com"
    ],
    "dns": true,
    "rdap": true,
    "ssl": true,
    "http": true,
    "maxConcurrency": 3,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("insight.solutions/domain-intelligence-api").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "domains": [
        "apify.com",
        "notion.so",
        "bbc.co.uk",
        "stripe.com",
        "example.com",
    ],
    "dns": True,
    "rdap": True,
    "ssl": True,
    "http": True,
    "maxConcurrency": 3,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("insight.solutions/domain-intelligence-api").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "domains": [
    "apify.com",
    "notion.so",
    "bbc.co.uk",
    "stripe.com",
    "example.com"
  ],
  "dns": true,
  "rdap": true,
  "ssl": true,
  "http": true,
  "maxConcurrency": 3,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call insight.solutions/domain-intelligence-api --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,insight.solutions/domain-intelligence-api"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/thFlecsUyY88wRBmq/builds/101N0y4itZ0LtNQo7/openapi.json
