# Bulk WHOIS and Domain Lookup: RDAP, DNS, MX, SPF and DMARC (`keelandcharter/domain-rdap-dns-lookup`) Actor

Bulk WHOIS alternative using official RDAP registries plus DNS: registrar, creation and expiry dates, days to expiry, domain age, status, nameservers, DNSSEC, MX mail provider, SPF and DMARC policy. Thousands of domains per run, no contact data collected. $2 per 1,000 domains.

- **URL**: https://apify.com/keelandcharter/domain-rdap-dns-lookup.md
- **Developed by:** [Keel & Charter](https://apify.com/keelandcharter) (community)
- **Categories:** Developer tools, SEO tools, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 1,000 domain lookups

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 plus DNS, SPF and DMARC

Look up thousands of domains in one run and get the registration facts and email setup for each: registrar, creation date, expiry date and days left, status codes, nameservers, DNSSEC, A and MX records, the mail provider behind them, and SPF and DMARC checks.

Registration data comes from RDAP, the official successor to WHOIS that every gTLD registry now runs, found through the IANA RDAP registry. DNS comes from public DNS over HTTPS. No scraping of WHOIS websites, no captchas, no proxies.

Built and maintained by Keel & Charter.

### Use cases

- **Expiring domain watch.** Sort by `daysUntilExpiry` across a portfolio or a prospect list.
- **Lead enrichment.** Company age, registrar and mail provider (Google Workspace, Microsoft 365 and more) for B2B lists.
- **Email deliverability audits.** Who has SPF, who has DMARC and which policy (`none`, `quarantine`, `reject`).
- **Security and brand checks.** Status locks, DNSSEC and nameserver changes on lookalike domains.
- **Availability checks.** `registered: false` means the registry has no record of the name.

### Input

| Field | What it does |
|---|---|
| `domains` | Required. Domains or links, one per line. `https://www.example.org/page` becomes `example.org`. |
| `includeRdap` | Registration data. On by default. |
| `includeDns` | DNS records plus mail provider, SPF and DMARC. On by default. |
| `dnsRecordTypes` | Any of A, AAAA, MX, NS, TXT, CNAME, CAA. |
| `maxConcurrency` | Lookups at once (default 10). |

```json
{ "domains": ["apify.com", "github.com", "bbc.co.uk"] }
```

### Output

```json
{
  "domain": "apify.com",
  "registered": true,
  "registrar": "Amazon Registrar, Inc.",
  "registrarIanaId": "468",
  "createdAt": "2009-06-02T17:14:10Z",
  "expiresAt": "2035-06-02T17:14:10Z",
  "daysUntilExpiry": 3141,
  "ageDays": 6355,
  "status": ["client transfer prohibited"],
  "nameservers": ["ns-1225.awsdns-25.org", "ns-449.awsdns-56.com"],
  "dnssec": true,
  "dns": { "a": ["..."], "mx": ["..."], "ns": ["..."], "txt": ["..."] },
  "mailProvider": "Google Workspace",
  "hasSpf": true,
  "hasDmarc": true,
  "dmarcPolicy": "reject",
  "checkedAt": "2026-10-26T02:46:36+00:00"
}
```

### Pricing

Pay per event, no subscription and no separate compute charge:

| Event | Price |
|---|---|
| Domain lookup | $0.002 per domain ($2 per 1,000) |
| Actor start | $0.00005 per run |

Example: 5,000 domains cost about $10. Invalid input, email addresses and lookups that return no data at all are skipped and never charged. Set a maximum cost per run in the run options and the Actor stops cleanly when it is reached.

Pricing may change; any change follows Apify's notice rules.

### Good to know

- **Privacy first.** Registrant, admin and tech contacts are never read or stored, only the registrar company. Email addresses in DNS text (such as DMARC report inboxes) are replaced with `[email removed]`. Email addresses are not accepted as input.
- **Some country domains have no RDAP yet** (for example .de and .io). For those you still get DNS, mail provider, SPF and DMARC, and `rdapError` explains why registration data is missing.
- **Subdomains work.** `shop.example.org` is looked up as `example.org`.
- Registries limit request rates, so each registry server gets at most 3 requests at a time with automatic retry.

### Feedback

Want another field or check? Open an issue on the Issues tab and Keel & Charter will take a look.

### FAQ

**Is this a WHOIS lookup?**
Yes, through RDAP, which ICANN requires every gTLD registry and registrar to run. Since January 2025 it is the definitive source for gTLD registration data (.com, .name and .post registries still keep a WHOIS service too). You get the same registration facts in structured JSON, without scraping WHOIS sites.

**Can I find which email provider a company uses?**
Yes. mailProvider is read from MX records, for example Google Workspace or Microsoft 365.

### More from Keel & Charter

- [Greenhouse, Lever, Ashby and Workable Jobs Scraper](https://apify.com/keelandcharter/ats-jobs-feed)
- [Workday Jobs Scraper](https://apify.com/keelandcharter/workday-jobs-feed)
- [Wayback Machine Domain History](https://apify.com/keelandcharter/wayback-domain-history)
- [South Carolina Short Term Rental Regulations](https://apify.com/keelandcharter/sc-short-term-rental-rules)

# Actor input Schema

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

Domains or website links, one per line, for example apify.com or https://www.example.org/page. Invalid lines are skipped and never charged.

## `includeRdap` (type: `boolean`):

Registrar, created, updated and expiry dates, status, nameservers and DNSSEC from the official registry.

## `includeDns` (type: `boolean`):

DNS records plus mail provider, SPF and DMARC checks.

## `dnsRecordTypes` (type: `array`):

Any of A, AAAA, MX, NS, TXT, CNAME, CAA.

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

Domains looked up at the same time. Each registry server also gets at most 3 requests at once.

## Actor input object example

```json
{
  "domains": [
    "apify.com",
    "github.com",
    "bbc.co.uk"
  ],
  "includeRdap": true,
  "includeDns": true,
  "dnsRecordTypes": [
    "A",
    "AAAA",
    "MX",
    "NS",
    "TXT"
  ],
  "maxConcurrency": 10
}
```

# Actor output Schema

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

All domain records returned by the run, 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",
        "github.com",
        "bbc.co.uk"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("keelandcharter/domain-rdap-dns-lookup").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",
        "github.com",
        "bbc.co.uk",
    ] }

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

```

## MCP server setup

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

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/l0Sv9KZ47g7bHg4oL/builds/e3waZOy1FaSiTQDzw/openapi.json
