# Domain Lookup – RDAP WHOIS, DNS, SPF/DMARC & SSL Expiry (Bulk) (`pinkish_armada/domain-intel`) Actor

Bulk domain checker using official RDAP (the WHOIS successor), DNS and TLS: registrar, creation and expiry dates, status, nameservers, DNSSEC, A/MX/TXT records, SPF and DMARC, email provider and SSL certificate expiry.

- **URL**: https://apify.com/pinkish_armada/domain-intel.md
- **Developed by:** [Phuc Tiet](https://apify.com/pinkish_armada) (community)
- **Categories:** Developer tools, SEO tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 domain checkeds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

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

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Domain Lookup: RDAP WHOIS, DNS, SPF/DMARC & SSL Expiry (Bulk)

Check thousands of domains in one run and get one clean row per domain with:

- **Registration data** from the registry's official **RDAP** service (the modern, machine-readable replacement for WHOIS): registrar, creation date, expiry date, domain age, days until expiry, status codes, transfer lock, name servers and DNSSEC. Unregistered domains are flagged.
- **DNS records:** A, AAAA, CNAME, MX, NS, TXT, CAA and SOA.
- **Email security:** SPF (present? `-all`/`~all`? duplicates?), DMARC policy (`none`/`quarantine`/`reject`) and the detected **mail provider** (Google Workspace, Microsoft 365, Zoho, Proofpoint...).
- **SSL/TLS certificate:** valid or not, issuer, expiry date, **days until expiry**, TLS version, and whether the certificate covers the host.

It's useful for domain portfolio and expiry monitoring, lead qualification (domain age, mail provider), email deliverability audits, security reviews, brand protection and AI agents that need facts about a domain.

### Why this one

- **All in one call.** Registration, DNS, email security and SSL for $1 per 1,000 domains. Many tools charge that for WHOIS alone.
- **Official sources only.** RDAP endpoints come from the IANA bootstrap registry, DNS from public resolvers, and SSL from a direct TLS handshake. There is no scraping of WHOIS websites.
- **No personal data.**
  - Registrant names, emails, phones and addresses are never returned.
  - Only registrar and domain facts are included, plus the registrar's published abuse contact.
- **Polite and robust.**
  - At most 3 parallel requests per RDAP server.
  - `Retry-After` is honoured. If a registry rate-limits the run, its registration lookups are skipped with a clear note instead of hammering it.
  - Timeouts and retries are built in, and invalid inputs are reported, not charged.
- **Accepts messy input.** URLs, `www.` hosts and subdomains are normalised to the registrable domain using the Public Suffix List (`https://www.bbc.co.uk/news` becomes `bbc.co.uk`).

### Input

| Field | Default | Description |
|---|---|---|
| `domains` | – | Domains, hostnames or URLs (required). Up to 10,000 per run. |
| `checkRegistration` | true | RDAP registration data. |
| `checkDns` | true | DNS records, SPF, DMARC, mail provider. |
| `checkTls` | true | SSL certificate on port 443. |
| `dnsServers` | `1.1.1.1`, `8.8.8.8` | Resolvers to use. |
| `maxConcurrency` | 10 | Domains checked in parallel. |
| `timeoutSecs` | 15 | Per lookup. |

```json
{ "domains": ["github.com", "https://www.bbc.co.uk/news", "example.org"] }
```

### Output

One dataset row per domain (shortened):

```json
{
  "input": "github.com",
  "domain": "github.com",
  "status": "ok",
  "registered": true,
  "registrar": "MarkMonitor Inc.",
  "registrarIanaId": "292",
  "registrarAbuseEmail": "abusecomplaints@markmonitor.com",
  "createdAt": "2007-10-09T18:20:50Z",
  "expiresAt": "2028-10-09T18:20:50Z",
  "domainAgeDays": 6937,
  "daysUntilExpiry": 733,
  "domainStatus": ["client delete prohibited", "client transfer prohibited", "client update prohibited"],
  "transferLocked": true,
  "dnssec": false,
  "nameservers": ["dns1.p08.nsone.net", "ns-421.awsdns-52.com"],
  "resolves": true,
  "dns": { "a": ["140.82.114.3"], "aaaa": [], "mx": [{ "priority": 0, "exchange": "github-com.mail.protection.outlook.com" }], "ns": ["..."], "txt": ["..."], "caa": ["0 issue \"digicert.com\""], "soa": { "primaryNs": "dns1.p08.nsone.net", "serial": 1656468023 } },
  "email": {
    "hasMx": true,
    "provider": "Microsoft 365",
    "spf": { "present": true, "allQualifier": "softfail", "multipleRecords": false, "record": "v=spf1 ip4:192.30.252.0/22 ... ~all" },
    "dmarc": { "present": true, "policy": "quarantine", "subdomainPolicy": "reject", "pct": 100 }
  },
  "tls": { "valid": true, "issuer": "Sectigo Limited", "validTo": "2026-11-29T23:59:59.000Z", "daysUntilExpiry": 54, "protocol": "TLSv1.3", "coversHost": true },
  "checkedAt": "2026-10-07T04:50:00.000Z"
}
```

**Unregistered domains** get `"registered": false`, which makes this a cheap bulk availability check.

**Partial results:**

- If a registry has no RDAP service (see Limitations), `registered` is `null` and `registrationNote` explains why. DNS and SSL data are still returned.
- Invalid inputs and IP addresses get `"status": "error"` with `errorCode` and are **not charged**.

A run summary (counts, plus domains and certificates expiring within 30 days) is saved as `OUTPUT`.

### How much does it cost to look up WHOIS, DNS and SSL for domains?

Pay per event, plus a tiny Actor start fee ($0.00005 per GB of memory):

- **Domain checked:** $0.001 per domain ($1.00 per 1,000 domains), covering every enabled check.

Platform usage is included in the price. Invalid inputs, duplicates and domains where every lookup failed are **not charged**. If you set a maximum cost per run, the Actor stops when it is reached.

### Limitations (honest)

- **Registration data only where an RDAP service exists.** This covers all generic TLDs (.com, .net, .org, .dev, .app, .ai, .xyz, ...) and many country codes (.uk, .au, .fr, .nl, ...).
  - Some ccTLDs, such as .de, .io, .co and .nz, publish no RDAP in the IANA bootstrap. For those you get DNS and SSL only.
  - Registries can rate-limit; affected rows say so in `registrationNote`.
- **Registrant details are deliberately excluded.** Most are redacted under GDPR anyway.
- **DNS answers are as seen by the chosen public resolvers at run time.** Geo-DNS can differ by location.
- **SSL is checked on port 443 of the host you entered.** For a bare domain that is the apex, not `www.`.

### FAQ

**Is this WHOIS?** RDAP is the ICANN-mandated successor to WHOIS: the same registration data, as structured JSON, from the registries themselves.

**Can I monitor expiries?** Yes. Schedule the Actor (e.g. weekly) and filter on `daysUntilExpiry` and `tls.daysUntilExpiry`. The `OUTPUT` summary counts both.

**How fast is it?** Around 10–20 domains per second with default settings.

### Use it from AI agents (MCP), the API, Make, Zapier and n8n

- **AI agents and MCP clients** (Claude, ChatGPT, Cursor, VS Code): add `https://mcp.apify.com?tools=pinkish_armada/domain-intel` as an MCP server, and your agent can look up RDAP WHOIS, DNS, SPF/DMARC and SSL expiry for many domains as a tool call.
- **API**: run it and get the results in one request:

```bash
curl -X POST "https://api.apify.com/v2/acts/pinkish_armada~domain-intel/run-sync-get-dataset-items?token=YOUR_APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"domains":["apify.com","example.org"]}'
```

- **No-code**: use the official Apify apps for **Make**, **Zapier** and **n8n** ("Run an Actor"), then send results to Google Sheets, Slack, Airtable or your database. You can also schedule runs in Apify Console and add a webhook or email integration.

### Related tools

- [Sitemap URL Extractor](https://apify.com/pinkish_armada/sitemap-url-extractor): list every URL of a site from its sitemaps, with optional 404 checks
- [Broken Link Checker](https://apify.com/pinkish_armada/broken-link-checker): crawl a website and report broken links, 404s and redirects
- [PDF to Markdown](https://apify.com/pinkish_armada/pdf-to-markdown): turn PDFs (including scans, via OCR) into Markdown, text and tables
- [Office Docs to Markdown](https://apify.com/pinkish_armada/office-to-markdown): turn DOCX, PPTX, XLSX, HTML and EPUB into clean Markdown for LLMs and RAG

# Actor input Schema

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

Domain names (<code>example.com</code>), hostnames (<code>www.example.co.uk</code>) or full URLs. Registration data is looked up for the registrable domain. Duplicates are removed. Up to 10,000 per run.

## `checkRegistration` (type: `boolean`):

Registrar, creation/expiry/update dates, domain age, days until expiry, status codes, transfer lock, registry name servers and DNSSEC, from the registry's official RDAP service. Unregistered domains are reported as <code>registered: false</code>.

## `checkDns` (type: `boolean`):

A, AAAA, CNAME, MX, NS, TXT, CAA and SOA records, plus SPF and DMARC analysis and the detected mail provider.

## `checkTls` (type: `boolean`):

Connects to port 443 and reports certificate validity, issuer, expiry date, days until expiry, TLS version and whether the certificate covers the host.

## `dnsServers` (type: `array`):

Resolvers to query (IP addresses).

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

Domains checked at the same time. RDAP servers are additionally limited to 3 parallel requests each.

## `timeoutSecs` (type: `integer`):

Maximum time for each network lookup (RDAP, DNS, TLS) before it is reported as failed.

## Actor input object example

```json
{
  "domains": [
    "apify.com",
    "example.org",
    "bbc.co.uk"
  ],
  "checkRegistration": true,
  "checkDns": true,
  "checkTls": true,
  "dnsServers": [
    "1.1.1.1",
    "8.8.8.8"
  ],
  "maxConcurrency": 10,
  "timeoutSecs": 15
}
```

# Actor output Schema

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

Registrar, dates, age, expiry, status, DNSSEC, DNS records, SPF/DMARC, mail provider and SSL certificate per domain, or errorCode/error.

## `summary` (type: `string`):

Domains checked, registered/not registered, invalid, failed, and domains or certificates expiring within 30 days.

# 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",
        "example.org",
        "bbc.co.uk"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("pinkish_armada/domain-intel").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",
        "example.org",
        "bbc.co.uk",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("pinkish_armada/domain-intel").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",
    "example.org",
    "bbc.co.uk"
  ]
}' |
apify call pinkish_armada/domain-intel --silent --output-dataset

```

## MCP server setup

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

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/P9Htp04bNziK65TRT/builds/USafIBA63NBBA6qp1/openapi.json
