# Domain Registration Lookup Scraper (`automation-lab/domain-rdap-lookup`) Actor

Look up domain registration, registrar, status, nameserver, and expiry data through authoritative public RDAP services.

- **URL**: https://apify.com/automation-lab/domain-rdap-lookup.md
- **Developed by:** [Stas Persiianenko](https://apify.com/automation-lab) (community)
- **Categories:** Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event

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/platform/actors/running/actors-in-store#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 Registration Lookup Scraper

Refresh registrar, registration, expiry, status, nameserver, DNSSEC, and public entity-handle records for supplied domains through authoritative public RDAP services.

**Domain Registration Lookup Scraper** routes every domain with IANA's current DNS RDAP bootstrap data. It queries the registry's structured JSON endpoint directly and records the source URL and retrieval time, making the output practical for portfolio monitoring, risk review, and repeatable enrichment.

### What does Domain Registration Lookup Scraper do?

The Actor accepts up to 1,000 domain names or URLs per run.

For each unique domain, it:

1. normalizes URLs and internationalized domain names;
2. downloads IANA's current TLD-to-RDAP service map;
3. selects the authoritative registry service;
4. requests the domain's RDAP record;
5. normalizes dates, registrar data, statuses, nameservers, DNSSEC, and entities;
6. saves a typed dataset row with source and retrieval evidence.

It does not scrape search-engine pages or guess registration details from DNS records.

### Who is this domain registration lookup for?

- **IT operations teams** refreshing renewal and registrar inventories.
- **Security analysts** enriching suspicious-domain lists with age and status signals.
- **Brand protection teams** tracking lookalike or campaign domains.
- **Domain portfolio managers** checking expiry dates and nameserver changes.
- **Data engineers** adding normalized RDAP records to scheduled workflows.
- **Due-diligence teams** preserving source URLs and retrieval timestamps for review.

### Why use authoritative RDAP data?

RDAP is the structured JSON successor to free-form WHOIS responses.

This Actor uses the IANA bootstrap registry to discover each TLD's published RDAP service instead of depending on one third-party aggregator.

Benefits include:

- consistent typed output across registries;
- traceable authoritative source endpoints;
- explicit event, status, entity, and DNSSEC fields;
- URL, duplicate, and internationalized-domain normalization;
- uncharged error records when a domain cannot be resolved;
- bounded concurrency for registry rate-limit safety.

For legacy raw WHOIS text, use [WHOIS Lookup](https://apify.com/automation-lab/whois-lookup) instead.

### What domain registration data can I extract?

| Field | Description |
| --- | --- |
| `domain` | Normalized ASCII domain returned by RDAP |
| `unicodeDomain` | Unicode domain form when the registry supplies it |
| `registryHandle` | Registry identifier for the domain object |
| `registrar` | Registrar name from the registrar entity |
| `registrarHandle` | Public registrar entity handle |
| `registrationDate` | Registration event timestamp |
| `expirationDate` | Registry expiration event timestamp |
| `lastChangedDate` | Latest domain-change timestamp when exposed |
| `domainAgeDays` | Whole days since registration |
| `daysUntilExpiration` | Whole days until expiration |
| `statuses` | Registry status codes |
| `nameservers` | Nameserver hostnames in the registration record |
| `dnssecSigned` | Signed-delegation indicator when exposed |
| `entityHandles` | Public entity handles, roles, and names |
| `rdapSourceUrl` | Registry RDAP endpoint that supplied the record |
| `bootstrapPublication` | IANA bootstrap publication timestamp |
| `retrievedAt` | UTC lookup timestamp |
| `lookupStatus` | `found`, `not_found`, or `failed` |
| `error` | Explanation for an unresolved lookup |

Registry redaction policies vary. Fields that are absent upstream remain `null` or empty; the Actor does not infer private registration data.

### How to run a domain registration lookup

1. Open the Actor in Apify Console.
2. Add domain names or website URLs to **Domains**.
3. Leave **Maximum concurrency** at `5` unless a registry requires slower requests.
4. Click **Start**.
5. Open the default dataset to review or export the rows.
6. Schedule the Task when you need recurring snapshots.

A practical first input is:

```json
{
  "domains": [
    "apify.com",
    "wikipedia.org",
    "cloudflare.com"
  ],
  "maxConcurrency": 3
}
```

### Input parameters

| Parameter | Type | Required | Default | Limits | Description |
| --- | --- | --- | --- | --- | --- |
| `domains` | string\[] | Yes | Prefilled examples | 1–1,000 | Domain names or URLs to normalize, deduplicate, and resolve |
| `maxConcurrency` | integer | No | `5` | 1–10 | Maximum simultaneous registry requests |

Accepted domain inputs include:

```text
apify.com
https://www.apify.com/store
münchen.de
```

The Actor removes a leading `www`, strips URL paths, converts Unicode hostnames to ASCII for lookup, and skips duplicates after normalization.

Malformed input fails the run before any domain requests are made.

### Domain registration lookup output example

A successful `apify.com` lookup produces this shape (some arrays shortened):

```json
{
  "domain": "apify.com",
  "unicodeDomain": null,
  "registryHandle": "1586855587_DOMAIN_COM-VRSN",
  "registrar": "Amazon Registrar, Inc.",
  "registrarHandle": "468",
  "registrationDate": "2009-06-02T17:14:10Z",
  "expirationDate": "2035-06-02T17:14:10Z",
  "lastChangedDate": "2025-05-25T23:25:20Z",
  "domainAgeDays": 6282,
  "daysUntilExpiration": 3214,
  "statuses": ["client transfer prohibited"],
  "nameservers": ["ns-1114.awsdns-11.org"],
  "dnssecSigned": false,
  "entityHandles": [
    {
      "handle": "468",
      "roles": ["registrar"],
      "name": "Amazon Registrar, Inc."
    }
  ],
  "rdapSourceUrl": "https://rdap.verisign.com/com/v1/domain/apify.com",
  "bootstrapPublication": "2026-08-13T20:00:01Z",
  "retrievedAt": "2026-08-14T06:30:00.000Z",
  "lookupStatus": "found",
  "error": null
}
```

Dates and registry handles above are illustrative snapshots; live registry records can change.

### How much does it cost to look up domain registration records?

The Actor uses pay-per-event pricing.

- A one-time **Run started** event costs **$0.001** per run.
- Each successfully resolved domain uses one **Domain resolved** event.
- Failed and `not_found` rows are not charged per domain.
- The per-domain rate decreases across Apify pricing tiers.

At the BRONZE rate of **$0.0016 per resolved domain**:

| Successful domains | Example total |
| ---: | ---: |
| 1 | $0.0026 |
| 10 | $0.017 |
| 100 | $0.161 |
| 1,000 | $1.601 |

Your active tier is shown in Apify Console. Runtime infrastructure is included in pay-per-event billing; registry rate limits can affect duration but not the number of successfully resolved domain events.

### Monitor a domain portfolio

Create an Apify Task with the portfolio's domains and schedule it daily, weekly, or monthly.

Send each finished dataset to a webhook, cloud storage, spreadsheet, or database.

Compare records by `domain` and flag changes in:

- `registrar`;
- `expirationDate`;
- `statuses`;
- `nameservers`;
- `dnssecSigned`.

Keep historical datasets if you need change history. The Actor returns current snapshots; it does not maintain an internal history database or send alerts by itself.

### Security and risk enrichment workflow

For incident-response or brand-protection lists:

1. supply normalized or raw URLs from your detection system;
2. inspect `domainAgeDays` for recently registered domains;
3. retain `rdapSourceUrl` as evidence;
4. combine `statuses` and nameservers with DNS or certificate data;
5. route `failed` rows into a bounded retry queue.

Registration metadata is one signal, not proof that a domain is malicious or trustworthy.

### Export and integrations

The default dataset can be downloaded as JSON, CSV, Excel, XML, RSS, or JSONL.

Common integrations include:

- Google Sheets for renewal inventories;
- Airtable for portfolio review;
- Slack or email workflows for expiry thresholds;
- databases and data warehouses for historical comparison;
- security automation platforms for domain enrichment;
- Zapier and Make for no-code routing.

Use `domain` as the stable join key and `retrievedAt` as the observation time.

### Run through the Apify API with cURL

```bash
curl -X POST \
  "https://api.apify.com/v2/acts/automation-lab~domain-rdap-lookup/runs?token=$APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "domains": ["apify.com", "wikipedia.org"],
    "maxConcurrency": 2
  }'
```

To wait for completion and receive dataset items directly:

```bash
curl -X POST \
  "https://api.apify.com/v2/acts/automation-lab~domain-rdap-lookup/run-sync-get-dataset-items?token=$APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"domains":["apify.com"]}'
```

### Run with JavaScript

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

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('automation-lab/domain-rdap-lookup').call({
  domains: ['apify.com', 'github.com', 'cloudflare.com'],
  maxConcurrency: 3,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

### Run with Python

```python
import os
from apify_client import ApifyClient

client = ApifyClient(os.environ['APIFY_TOKEN'])
run = client.actor('automation-lab/domain-rdap-lookup').call(run_input={
    'domains': ['apify.com', 'wikipedia.org'],
    'maxConcurrency': 2,
})
items = client.dataset(run['defaultDatasetId']).list_items().items
print(items)
```

### Use Domain Registration Lookup Scraper with MCP

Add the Actor to Claude Code:

```bash
claude mcp add --transport http apify \
  "https://mcp.apify.com?tools=automation-lab/domain-rdap-lookup"
```

#### Claude Desktop setup

Add this server in Claude Desktop's MCP configuration. The same JSON shape works for supported editor clients:

```json
{
  "mcpServers": {
    "apify": {
      "url": "https://mcp.apify.com?tools=automation-lab/domain-rdap-lookup"
    }
  }
}
```

#### Cursor setup

Open Cursor's MCP settings and add the `apify` server URL from the JSON above.

#### VS Code setup

Add the same HTTP MCP server URL through your VS Code MCP extension or workspace MCP configuration.

Example prompts:

- “Look up the registration and expiry dates for these domains and return a table.”
- “Refresh this domain portfolio and show records expiring within 90 days.”
- “Resolve these incident URLs and list recently registered domains with their RDAP source.”

### Limits and expected failure behavior

- Coverage depends on IANA listing an RDAP service for the domain's TLD.
- Registry fields and redaction rules differ.
- Some registries omit expiration dates, registrar names, DNSSEC, or entity names.
- Registry rate limits can produce temporary `failed` records.
- A registry 404 produces an uncharged `not_found` row.
- The Actor does not query private registrar APIs, historical WHOIS databases, or paid ownership sources.
- The Actor does not determine availability for purchase; a missing RDAP record is not a purchase guarantee.
- The maximum input is 1,000 domains per run and concurrency is capped at 10.

For a throttled registry, reduce `maxConcurrency` and retry only the failed domains later.

### Troubleshooting

#### Why is the registrar or expiry date null?

The authoritative registry did not expose that field in its RDAP response. Check `rdapSourceUrl` to inspect the source record.

#### Why did I receive `not_found`?

The selected authoritative service returned HTTP 404. The domain may be unregistered, unsupported at that registry, or temporarily unavailable. Do not treat this alone as proof of purchase availability.

#### Why did I receive `failed`?

Review `error` and the run log. Temporary 429 or 5xx responses usually indicate registry throttling or an outage. Lower concurrency and retry the affected domains.

#### Why were fewer requests made than input rows?

Normalization removes leading `www`, strips URL paths, and deduplicates domains. `google.com` and `https://www.google.com/path` resolve once.

#### Can I use a proxy?

This Actor does not expose a proxy option because authoritative RDAP requests work directly and adding paid proxy traffic would increase cost without improving the normal route.

### Responsible use and legality

RDAP services publish registration data for legitimate technical, operational, security, and legal purposes. Users remain responsible for complying with registry terms, applicable law, and Apify's policies.

Do not use the output to harass registrants, bypass redaction, send unsolicited messages, or make unsupported ownership claims. Entity data can be redacted, privacy-proxied, stale, or incomplete. Minimize retention and access when records contain personal information.

### Frequently asked questions

#### Is RDAP the same as WHOIS?

RDAP serves a similar registration lookup purpose but uses structured JSON, standardized links, and clearer status and entity objects. WHOIS commonly returns free-form text.

#### Does the Actor return historical registration records?

No. It returns the current public registry response. Preserve scheduled dataset snapshots if you need your own history.

#### Does it find domains by keyword?

No. Supply exact domains or URLs. The Actor does not search for brand variants or newly registered domains.

#### Are failed domains billed?

The run start event still applies, but the per-domain event is charged only after the registry successfully resolves a domain.

#### Can I look up internationalized domains?

Yes. Unicode hostnames are converted to ASCII for routing and lookup. `unicodeDomain` is populated when the registry returns that form.

#### How fresh is the data?

Every run queries the registry service selected from the current IANA bootstrap response. Freshness of each field is controlled by that registry.

### Related Automation Lab Actors

- [WHOIS Lookup](https://apify.com/automation-lab/whois-lookup) for legacy raw WHOIS responses and parsed contact fields.
- [SSL Certificate Checker](https://apify.com/automation-lab/ssl-certificate-checker) for certificate validity, issuer, and expiry checks.
- [MX Record Checker](https://apify.com/automation-lab/mx-record-checker) for domain mail-routing records.

Combine these Actors when a workflow needs registration, DNS, and certificate evidence rather than RDAP alone.

# Actor input Schema

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

Domain names or URLs to look up. URLs are reduced to their hostname, leading www is removed, internationalized names are converted to ASCII, and duplicates are skipped. Maximum 1,000 entries.

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

Number of RDAP requests processed in parallel. Keep this low for large portfolios because registry rate limits vary.

## Actor input object example

```json
{
  "domains": [
    "apify.com",
    "wikipedia.org",
    "cloudflare.com"
  ],
  "maxConcurrency": 5
}
```

# Actor output Schema

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

Domain registration lookup records 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",
        "wikipedia.org",
        "cloudflare.com"
    ],
    "maxConcurrency": 5
};

// Run the Actor and wait for it to finish
const run = await client.actor("automation-lab/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": [
        "apify.com",
        "wikipedia.org",
        "cloudflare.com",
    ],
    "maxConcurrency": 5,
}

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

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,automation-lab/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/N73APzmsJJrrLgLWT/builds/4uQSa8lPBVgGTFdQ6/openapi.json
