# Domain RDAP Lookup: modern WHOIS for any TLD (`br_data_hub/domain-rdap-lookup`) Actor

Bulk RDAP lookup on each TLD's official registry server (IANA bootstrap): registrar, creation, update and expiry dates, domain age, EPP status, nameservers, DNSSEC, registrar abuse contact and ready-made alerts. No personal data.

- **URL**: https://apify.com/br_data_hub/domain-rdap-lookup.md
- **Developed by:** [br_data_hub](https://apify.com/br_data_hub) (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 $1.05 / 1,000 domain records

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?

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 RDAP Lookup: modern WHOIS for any TLD

Look up domains in bulk on **RDAP**, the protocol that replaced WHOIS, straight from the **official registry server of each TLD**. The right server is found through the IANA bootstrap file (`data.iana.org/rdap/dns.json`, RFC 9224), so `.com`, `.org`, `.dev`, `.cz`, `.no` and the 1,000+ other TLDs with RDAP all work without configuration. Every answer comes back in the same flat format, with ready-made alerts.

Typical uses: phishing and fraud triage (how old is this domain?), expiry monitoring of your portfolio, lead qualification, brand protection, and security tools or AI agents that need clean domain facts instead of raw WHOIS text.

### What you get per domain

- `registrar`, `registrarIanaId`, `registrarUrl`, and the registrar's **abuse contact** (`abuseEmail`, `abusePhone`)
- `createdAt`, `updatedAt`, `expiresAt` (ISO 8601, UTC), plus `domainAgeDays` and `daysUntilExpiry`
- `eppStatus`: EPP status codes such as `clientTransferProhibited` or `clientHold` (RFC 8056 mapping; RDAP `active` becomes `ok`)
- `nameservers` (lower case) and `dnssec` (`true`, `false`, or `null` when the registry does not say)
- `alerts`, ready to filter on:
  - `EXPIRES_IN_30_DAYS`: expires within 30 days (`EXPIRED` if the date has passed)
  - `REGISTERED_LESS_THAN_30_DAYS`: newly registered, a classic phishing signal
  - `CLIENT_HOLD` (and `SERVER_HOLD`): the domain is suspended and does not resolve
  - `PENDING_DELETE`: in redemption or about to be deleted
  - `NO_DNSSEC`: the registry reports the delegation as unsigned
- `rdapServer`, `rdapUrl` (the exact query, so you can check it) and `rdapTermsUrl` (the registry's terms of use)

**No personal data.** Registrant, administrative, technical and billing contacts are never read into the output, even when the server returns them. Only the registrar (a company) and its abuse mailbox are kept, and an abuse contact that is a named individual is dropped too.

### Input

| Field | Description |
|---|---|
| `domains` | Domain names, one per line (up to 10,000). URLs and e-mail addresses are accepted: the host is extracted, `www.` is removed, duplicates are skipped, and IDNs are converted to punycode. |
| `maxDomains` | Safety cap per run (default 1,000). |
| `requestsPerSecondPerServer` | Requests per second on each RDAP server (default 1, max 5). Different servers are queried in parallel. |
| `maxRetries` | Retries after HTTP 429, 5xx or network errors (default 5). |

The default input looks up four well-known domains on three registries and finishes in a few seconds.

#### Rate limits

Registries limit how fast you can query them. The Actor gives **each RDAP server its own queue**, spaces requests on it, and when a server answers **HTTP 429** it waits for the `Retry-After` header (or backs off exponentially) and keeps that server slower for the rest of the run. Servers with published strict limits, such as Norid (`.no`, 10 lookups per minute), are always queried at their limit. Big lists spread over many TLDs run fastest; 1,000 `.com` domains at the default speed take about 17 minutes; raise the run timeout (default 1 hour) for larger lists on a single TLD.

### Output example

```json
{
  "domain": "google.com",
  "tld": "com",
  "status": "registered",
  "registrar": "MarkMonitor Inc.",
  "registrarIanaId": "292",
  "abuseEmail": "abusecomplaints@markmonitor.com",
  "abusePhone": "+1.2083895740",
  "createdAt": "1997-09-15T04:00:00Z",
  "updatedAt": null,
  "expiresAt": "2028-09-14T04:00:00Z",
  "domainAgeDays": 10637,
  "daysUntilExpiry": 684,
  "eppStatus": ["clientDeleteProhibited", "clientTransferProhibited", "clientUpdateProhibited"],
  "nameservers": ["ns1.google.com", "ns2.google.com", "ns3.google.com", "ns4.google.com"],
  "dnssec": true,
  "alerts": [],
  "rdapServer": "rdap.verisign.com",
  "rdapUrl": "https://rdap.verisign.com/com/v1/domain/google.com",
  "rdapTermsUrl": "https://www.verisign.com/domain-names/registration-data-access-protocol/terms-service/index.xhtml",
  "checkedAt": "2026-10-30T12:00:00Z",
  "error": null
}
```

`status` is one of:

| Status | Meaning | Charged |
|---|---|---|
| `registered` | The registry returned the domain | Yes |
| `not_found` | The registry answered 404: the domain is not registered (or is reserved) | No |
| `unsupported_tld` | The TLD has no RDAP server in the IANA bootstrap file | No |
| `restricted_tld` | The registry's terms do not allow this use (currently `.br`, see below) | No |
| `invalid` | The input is not a domain name | No |
| `error` | The server failed or kept rate limiting after all retries; see `error` | No |

`updatedAt` is the registry's `last changed` event. Some registries (Verisign for `.com` and `.net`) only publish the date their RDAP database was refreshed, which is not a change to the domain, so it stays `null`.

### How much does it cost?

Pay per event: **`domain`**, charged once per domain the registry returned (`status: registered`). Not-found, unsupported, invalid and failed lookups are free. Apify's standard **`apify-actor-start`** event (US$ 0.00005 per run) also applies. No platform usage is billed on top.

Price: **US$ 0.0015 per domain (US$ 1.50 per 1,000)**. How it was set:

- Apify compute costs US$ 0.20 per compute unit (1 CU = 1 GB of memory for 1 hour). The Actor runs with 128 MB, the platform minimum. Peak memory measured locally was 65 MB for 600 domains and did not grow with the list.
- Time is spent waiting on the registries' rate limits, not computing. At the default 1 request per second per server, a domain costs at most 0.125 GB × 1 s / 3,600 = 0.000035 CU = **US$ 0.000007**. On the strictest servers (Norid, 6 s per domain) it costs US$ 0.00004. Start-up (about 3 s) adds US$ 0.00002 per run.
- After Apify's 20% commission, US$ 0.0015 leaves US$ 0.0012 per domain, more than 30 times the worst-case compute cost, so runs with few domains still cover start-up.

The Apify Store has several RDAP or WHOIS Actors, priced between about US$ 0.0005 and US$ 0.004 per domain (October 2026). US$ 0.0015 sits in the lower half, and every row here also has the domain's age, the registrar's abuse contact and alerts.

**$0.0015 per domain record** (`domain` event, pay per event). Charged once per domain the registry returned (status registered). Not found, invalid, unsupported or failed lookups are free.

| You get | Free tier | Bronze tier (10% off) | Gold tier (30% off) |
|---|---|---|---|
| 100 domain records | $0.15 | $0.14 | $0.10 |
| 1,000 domain records | $1.50 | $1.35 | $1.05 |
| 10,000 domain records | $15.00 | $13.50 | $10.50 |

Discounts follow your Apify subscription tier: Bronze 10%, Silver 20%, Gold and above 30%. No subscription to this Actor and no charge for platform usage: you pay only for results.
The Apify Free plan includes $5 of monthly credit, enough for about **3,333 domain records** at the list price.
You can cap the cost of any run with **Maximum cost per run**; the Actor stops when it is reached.

### Data source

- **IANA RDAP bootstrap file** (`https://data.iana.org/rdap/dns.json`): the official list of RDAP servers per TLD (RFC 9224). Public, and read once per run. If it cannot be reached, the Actor uses a copy bundled with it (servers rarely move) and says so in the log.
- **Each TLD's registry RDAP server**, for example Verisign for `.com`/`.net`, Public Interest Registry for `.org` and CZ.NIC for `.cz`. gTLD registries are required by ICANN to run public RDAP. Each registry has its own terms of use, linked in `rdapTermsUrl`. They allow lawful use and forbid high-volume abuse, spam and building copies of their database. This Actor only answers the lookups you ask for, at a polite rate, and keeps nothing between runs.
- **`.br` is not looked up.** Registro.br (NIC.br) runs an RDAP server (`rdap.registro.br`), but its terms forbid distribution, commercialization and reproduction of `.br` registration data. A paid Actor would be commercializing it, so `.br` domains come back as `restricted_tld` and are not charged. Use registro.br directly for `.br`.

Registries limit queries per IP address, and cloud IPs are shared, so a busy registry may answer HTTP 429 more often than from your own machine. The Actor then waits and retries; a domain that is still refused comes back as `error` and is not charged.

This Actor is independent and is not affiliated with, endorsed by or sponsored by IANA, ICANN, Verisign, NIC.br or any other registry; their names are used only to describe where the data comes from.

### More questions

#### What is the difference between RDAP and WHOIS?

RDAP is the protocol that replaced WHOIS for gTLDs. It returns JSON instead of free text, and each TLD has one official server, listed by IANA. This Actor reads that list, queries the registry's own server and flattens the answer, so `.com`, `.org`, `.cz` or `.dev` all come back with the same fields.

#### Can I paste URLs, e-mail addresses or subdomains?

URLs and e-mail addresses, yes: the host is extracted, a leading `www.` is removed, duplicates are skipped and internationalized names are converted to punycode. Other subdomains (`shop.example.com`) are not cut down to the registered domain: they are sent to the registry as typed, which normally answers "not found". Give the registered domain to get a record.

#### Why are the owner's name, e-mail and address missing?

On purpose. Most registries redact registrant data anyway, and the Actor never reads the registrant, administrative, technical or billing contacts into the output, even when a server sends them. You get the registrar, its role abuse mailbox and phone, and an abuse contact that is a named person is dropped too.

#### Does it work for country-code TLDs and `.br`?

Any TLD listed in the IANA RDAP bootstrap file works. A TLD that has no RDAP server there comes back as `unsupported_tld`, free. `.br` is never looked up because Registro.br forbids commercial use of its data: it comes back as `restricted_tld`, also free.

#### How fresh is the data?

Live: every run asks the registry at that moment, and `checkedAt` records when. Nothing is cached between runs. Only the list of RDAP servers can be older: if `data.iana.org` does not answer, the Actor uses a copy bundled with it and says so in the log.

#### Does `not_found` mean the domain is available to register?

It means the registry answered HTTP 404 for that name. That usually means it is not registered, but reserved or blocked names can also be missing, so confirm with a registrar before buying. `not_found` rows are free.

#### What happens when a registry rate-limits me?

On HTTP 429 the Actor waits for the server's `Retry-After` (or backs off), slows that server down for the rest of the run and tries again, up to `maxRetries` times. If the server still refuses, the row comes back with `status: error` and the reason, and it is not charged.

#### How do I find new or expiring domains in a list?

Filter on `alerts`: `REGISTERED_LESS_THAN_30_DAYS` for newly registered domains, `EXPIRES_IN_30_DAYS` or `EXPIRED` for renewals, `CLIENT_HOLD`, `SERVER_HOLD` or `PENDING_DELETE` for suspended ones. `domainAgeDays` and `daysUntilExpiry` give the exact numbers.

### Use it via API

Run it from any language and get the results as JSON. Replace `<YOUR_API_TOKEN>` with your [Apify API token](https://console.apify.com/settings/integrations).

```bash
curl -X POST "https://api.apify.com/v2/acts/br_data_hub~domain-rdap-lookup/run-sync-get-dataset-items?token=<YOUR_API_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"domains": ["google.com", "wikipedia.org", "nic.cz", "apify.com"]}'
```

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_API_TOKEN>")
run = client.actor("br_data_hub/domain-rdap-lookup").call(run_input={'domains': ['google.com', 'wikipedia.org', 'nic.cz', 'apify.com']})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)
```

You can also schedule runs, send results to webhooks, or connect the Actor to Make, Zapier, n8n, Google Sheets and other [integrations](https://docs.apify.com/platform/integrations).

### Use it with AI agents (MCP)

This Actor is ready for AI agents: typed input and output schemas, pay-per-event pricing, limited permissions and short runs.

- **Apify MCP server:** add `https://mcp.apify.com/?tools=br_data_hub/domain-rdap-lookup` to Claude, ChatGPT, Cursor, VS Code or any MCP client, and the agent can call this Actor as a tool.
- **Agent frameworks:** call it from LangChain, LlamaIndex, CrewAI or the OpenAI Agents SDK through the Apify integrations, or with the API call above.
- Results come as structured JSON with stable field names, documented in the **Output** tab.

### FAQ

#### Where does the data come from?

- **IANA RDAP bootstrap file** (`https://data.iana.org/rdap/dns.json`): the official list of RDAP servers per TLD (RFC 9224). Public, and read once per run. If it cannot be reached, the Actor uses a copy bundled with it (servers rarely move) and says so in the log. - **Each TLD's registry RDAP server**, for example Verisign for `.com`/`.net`, Public Interest Registry for `.org` and CZ.NIC for `.cz`. gTLD registries are required by ICANN to run public RDAP. Each registry has its own terms of use, linked in `rdapTermsUrl`. They allow lawful use and forbid high-volume abuse, spam and building copies of their database. This Actor only answers the lookups you ask for, at a polite rate, and keeps nothing between runs. - **`.br` is not looked up.** Registro.br (NIC.br) runs an RDAP server (`rdap.registro.br`), but its terms forbid distribution, commercialization and reproduction of `.br` registration data. A paid Actor would be commercializing it, so `.br` domains come back as `restricted_tld` and are not charged. Use registro.br directly for `.br`.

#### How much does it cost?

$0.0015 per domain record. Discounts follow your Apify subscription tier: Bronze 10%, Silver 20%, Gold and above 30%. See **How much does it cost?** above for examples.

#### Do I pay for errors or empty results?

No. Charged once per domain the registry returned (status registered). Not found, invalid, unsupported or failed lookups are free.

#### Can I run it on a schedule or connect it to other tools?

Yes. Use Apify schedules to run it daily or weekly, webhooks to get notified, and integrations such as Make, Zapier, n8n and Google Sheets. Everything also works through the API.

#### Can AI agents use it?

Yes. It works as a tool in the Apify MCP server and in agent frameworks, and AI agents can pay per event. See **Use it with AI agents (MCP)**.

#### Is it legal to use this data?

The Actor reads only public sources. You are responsible for how you use the data and for complying with the source's terms and with privacy laws such as GDPR.

#### I found a bug or need a feature. What should I do?

Open an issue in the **Issues** tab. We answer within 14 days, usually much sooner.

### More Actors from BR Data Hub

| Actor | What it does |
|---|---|
| [Email Domain Auth Checker: SPF, DKIM, DMARC, BIMI, MTA-STS](https://apify.com/br_data_hub/email-domain-auth-checker) | Bulk check SPF (real recursive lookup count vs |
| [CVE Risk Prioritizer, from NVD, CISA KEV and EPSS data](https://apify.com/br_data_hub/cve-risk-prioritizer) | One row per CVE built from public NVD (CVSS, CWE, affected products), CISA KEV (exploited, due date, ransomwar |
| [Food, Drug & Device Recalls Monitor (from openFDA data)](https://apify.com/br_data_hub/fda-recalls-monitor) | Food, drug and medical device recalls from the official openFDA enforcement API in one uniform format |
| [Clinical Trials Tracker, from ClinicalTrials.gov data](https://apify.com/br_data_hub/clinical-trials-tracker) | Search public ClinicalTrials.gov data by condition, drug, sponsor, phase, status and country, and track what c |

See all our Actors at [apify.com/br_data_hub](https://apify.com/br_data_hub).

### Usar em português

Informe uma lista de domínios e receba, direto do RDAP oficial de cada TLD (o protocolo que substituiu o WHOIS), o registrar, as datas de criação, atualização e expiração, a idade do domínio em dias, o status EPP, os nameservers, o DNSSEC e o contato de abuso do registrar. Também vêm alertas prontos: `EXPIRES_IN_30_DAYS`, `REGISTERED_LESS_THAN_30_DAYS` (sinal de phishing), `CLIENT_HOLD` e `NO_DNSSEC`. Dados pessoais de titulares e contatos não são coletados. A cobrança é por domínio encontrado; domínios inexistentes ou com erro não são cobrados. Domínios `.br` não são consultados, porque os termos do Registro.br proíbem a comercialização desses dados.

**Quanto custa:** $0.0015 por resultado (`domain`); 1.000 resultados saem por $1.50. Desconto pelo nível da assinatura Apify: Bronze 10%, Silver 20%, Gold ou acima 30%. Erros e consultas sem resultado não são cobrados. Use também pela API ou por agentes de IA no servidor MCP da Apify (`https://mcp.apify.com/?tools=br_data_hub/domain-rdap-lookup`).

# Actor input Schema

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

Enter domain names, one per line, up to 10,000 per run, e.g. google.com. URLs and e-mail addresses work too: the host is extracted, a leading www. is removed, duplicates are skipped and internationalized names (münchen.de) are converted to punycode.

## `maxDomains` (type: `integer`):

Set a safety cap, e.g. 1000. Domains after this number are ignored and not charged.

## `requestsPerSecondPerServer` (type: `integer`):

Set how fast each registry server is queried, e.g. 1. Different servers run in parallel, and servers with strict published limits (such as Norid for .no) are always queried more slowly. Keep it low to avoid HTTP 429.

## `maxRetries` (type: `integer`):

Set how many times to retry a domain after HTTP 429, a 5xx error or a network failure, e.g. 5. On 429 the Actor waits for the server's Retry-After and slows that server down.

## Actor input object example

```json
{
  "domains": [
    "google.com",
    "wikipedia.org",
    "nic.cz",
    "apify.com"
  ],
  "maxDomains": 1000,
  "requestsPerSecondPerServer": 1,
  "maxRetries": 5
}
```

# Actor output Schema

## `dataset` (type: `string`):

Dataset with all results

# 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": [
        "google.com",
        "wikipedia.org",
        "nic.cz",
        "apify.com"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("br_data_hub/domain-rdap-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": [
        "google.com",
        "wikipedia.org",
        "nic.cz",
        "apify.com",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("br_data_hub/domain-rdap-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": [
    "google.com",
    "wikipedia.org",
    "nic.cz",
    "apify.com"
  ]
}' |
apify call br_data_hub/domain-rdap-lookup --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,br_data_hub/domain-rdap-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/EIzoKXoYMJa1jfnjG/builds/bQW8piSIFwffl2Jvy/openapi.json
