# Bulk Domain RDAP Lookup: Expiry and Availability (`plainpipe/domain-rdap-lookup`) Actor

Bulk domain facts via RDAP: registered or available, registrar, status, expiry date, nameservers. Use when you need expiry or availability for many domains.

- **URL**: https://apify.com/plainpipe/domain-rdap-lookup.md
- **Developed by:** [Plain Pipe](https://apify.com/plainpipe) (community)
- **Categories:** Developer tools, Integrations
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$1.00 / 1,000 results

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

## Bulk Domain RDAP Lookup: Expiry and Availability

Bulk domain registration facts via RDAP: registered or available, registrar, status, created, updated and expiry dates, days to expiry, nameservers, DNSSEC.

**Use this when:** you need to know, for a list of domains, which are registered, who the registrar is and when each one expires.

### Why this one

- $1.00 per 1,000 results, one result per domain.
- Each row includes `daysUntilExpiry`, `dnssec`, `registrarIanaId` and the `rdapServer` that answered, next to the registrar, status codes, dates and nameservers.
- Reads the official RDAP registry services directly: no browser, no proxy, no HTML parsing. The prefilled example (2 domains) finishes in under 2 seconds in our test runs.
- Checked before each release against the prefilled input plus 6 edge-case inputs.

### What it does

For each domain name you give it, this Actor asks the registry's official RDAP server (Registration Data Access Protocol, the IETF standard for registration data) and returns one row: whether the name is registered, the sponsoring registrar and its IANA id, EPP status codes, creation, last-change and expiry dates, days left until expiry, nameservers and whether DNSSEC is signed.

The RDAP server for each top-level domain is looked up in the official [IANA RDAP bootstrap registry](https://www.iana.org/help/rdap-faq), so new TLDs work without changes. Data source: the public RDAP services of each domain registry (for example Verisign for .com and Public Interest Registry for .org); see [about.rdap.org](https://about.rdap.org/) and the [IANA RDAP FAQ](https://www.iana.org/help/rdap-faq). Each registry's own RDAP terms of service apply.

### Use cases

- Track renewals for a domain portfolio: export `expires` and `daysUntilExpiry` for every name each week.
- Spot names close to expiry or already expired (negative `daysUntilExpiry`).
- Audit nameserver and DNSSEC setup across all company domains.
- Check whether a list of possible new names is still unregistered before talking to a registrar.
- Confirm registrar lock status codes (`client transfer prohibited`) after a transfer or security review.

### How to use it

1. Add one or more **Domain names** (for example `apify.com` and `example.org`). Full URLs are fine; only the host name is used.
2. Set **Max results** if your list is long.
3. Click **Start**. One row per domain lands in the dataset.
4. Export the dataset as JSON, CSV or Excel, or read it through the Apify API.

### Input

| Field | What it is | Default | Example |
|---|---|---|---|
| `domains` (required) | Registered domain names. Full URLs are accepted (host name used); a leading `www.`, a trailing dot and letter case are normalised; duplicates are removed. Unicode names are converted to their `xn--` form. | none | `["apify.com", "https://www.python.org/about/", "bücher.com"]` |
| `maxItems` | Stop after this many domains, one result per domain (at most 10,000). | `100` | `500` |

A malformed entry (spaces, no top-level domain, invalid characters) fails the run before any request is made, so nothing is charged. The error message quotes the entry to fix.

### Output

One row per domain. Example from a real run (`python.org`):

```json
{
  "domain": "python.org",
  "registered": true,
  "available": false,
  "registrar": "Gandi SAS",
  "registrarIanaId": "81",
  "status": ["client transfer prohibited"],
  "created": "1995-03-27T05:00:00.545Z",
  "updated": "2026-08-12T05:01:11.536Z",
  "expires": "2033-03-28T05:00:00.000Z",
  "daysUntilExpiry": 2336,
  "nameservers": ["ns-1134.awsdns-13.org", "ns-2046.awsdns-63.co.uk", "ns-484.awsdns-60.com", "ns-981.awsdns-58.net"],
  "dnssec": false,
  "rdapServer": "https://rdap.publicinterestregistry.org/rdap/",
  "checkedAt": "2026-11-03T20:56:56.839Z"
}
```

| Field | Meaning |
|---|---|
| `domain` | The domain checked, lower case (`xn--` form for unicode names) |
| `registered`, `available` | Whether the registry holds a record; `available: true` when it answers "not found" |
| `registrar`, `registrarIanaId` | Sponsoring registrar organisation and its IANA id |
| `status` | EPP status codes, for example `client transfer prohibited` |
| `created`, `updated`, `expires` | Registration, last-change and expiry dates (ISO 8601 UTC) |
| `daysUntilExpiry` | Whole days until `expires`; negative when past expiry |
| `nameservers`, `dnssec` | Delegated nameservers; DNSSEC signed (`null` when the registry does not say) |
| `rdapServer`, `checkedAt` | RDAP server that answered, and when |

When the registry answers "not found" (HTTP 404), the row has `registered: false`, `available: true` and empty registration fields. That availability row is a documented result and is charged like any other row.

### Pricing

Pay per result: **$1.00 per 1,000 results** ($0.001 per result). You only pay for results the Actor returns. Set a maximum total charge on the run to cap your spend.

### Limits

- Polite by design: at most one request per second to each RDAP server, with a clear User-Agent and backoff when a server answers 429 or 5xx. Different registries are queried in parallel, so 1,000 `.com` names take about 20 minutes while a mixed list is faster.
- Enter registered names (`example.co.uk`, not `shop.example.co.uk`). Registries do not hold records for subdomains, and such names are reported as not found.
- `available: true` means the registry has no record. Some names are reserved or blocked by the registry and still cannot be registered; check with a registrar before buying.
- Some country-code TLDs do not run an RDAP server yet. For TLDs missing from the IANA bootstrap the Actor tries the public rdap.org redirector; if no RDAP answer comes back, the domain is skipped with a warning and not charged. If no domain could be checked, the run fails.
- Registry data only. The Actor does not follow links to registrar RDAP servers and does not return registrant or other party details.

### FAQ

**How much does a run cost?** $0.001 per domain returned; 1,000 domains cost $1.00. Domains that could not be checked are skipped and not charged.

**Is this the same as a classic port-43 lookup?** RDAP is the IETF successor protocol that registries now run; it gives the same registration facts as structured JSON. This Actor returns registry facts only, never owner details.

**Why is a domain missing from my results?** Its registry did not give an RDAP answer (no RDAP server for that country-code TLD, or repeated errors). The log names each skipped domain.

**Which export formats are there?** JSON, CSV, Excel, XML and HTML table from the dataset tab, or any of them through the Apify API.

**Can I run it on a schedule or from my own code?** Yes. Create a weekly schedule in Apify Console to watch expiry dates, or start runs and read results through the Apify API, webhooks or the Apify client libraries.

### Legal and data

This Actor processes only what you give it or public, non-personal technical data. It does not log in anywhere, does not collect personal data, and does not bypass paywalls, CAPTCHAs or access controls. You are responsible for having the right to process the inputs you provide.

It uses public RDAP services operated by domain registries, found through the IANA RDAP bootstrap registry (https://about.rdap.org/, https://www.iana.org/help/rdap-faq). Each registry's RDAP terms of service apply to your use of the results. Only the registrar's organization name and IANA id are kept from the entity data; registrant, administrative, technical and abuse contact records are never copied. It is not affiliated with or endorsed by IANA or any registry.

### Support

Open an issue on the Issues tab. Issues are answered within 14 days.

Built and maintained by Plain Pipe.

# Actor input Schema

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

Registered domain names to check, one per line. Examples: apify.com, example.org, bücher.com. Full URLs are accepted (the host name is used), a leading www. and a trailing dot are dropped, and duplicates are removed. Enter the registered name, not a subdomain.

## `maxItems` (type: `integer`):

Stop after this many domains (one result per domain). Default 100, maximum 10,000. Example: 500. You are charged per result.

## Actor input object example

```json
{
  "domains": [
    "apify.com",
    "example.org"
  ],
  "maxItems": 10
}
```

# Actor output Schema

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

No description

# 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"
    ],
    "maxItems": 10
};

// Run the Actor and wait for it to finish
const run = await client.actor("plainpipe/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",
        "example.org",
    ],
    "maxItems": 10,
}

# Run the Actor and wait for it to finish
run = client.actor("plainpipe/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",
    "example.org"
  ],
  "maxItems": 10
}' |
apify call plainpipe/domain-rdap-lookup --silent --output-dataset

```

## MCP server setup

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