# WHOIS & DNS Lookup — DNS-over-HTTPS + RDAP, No Scraping (`axery/whois-dns-lookup`) Actor

Look up DNS records and registration (WHOIS/RDAP) data for any domain via official public protocols: DNS-over-HTTPS and RDAP. No scraping, no anti-bot evasion — documented lookup services by design.

- **URL**: https://apify.com/axery/whois-dns-lookup.md
- **Developed by:** [Axery](https://apify.com/axery) (community)
- **Categories:** Developer tools, Other, Integrations
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.01 / 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.
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?

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

## WHOIS / DNS Lookup (DoH + RDAP)

Looks up DNS records and domain registration data for any domain, using two official, documented public protocols — **DNS-over-HTTPS** (RFC 8484) and **RDAP** (RFC 7480), the structured successor to legacy WHOIS text. No login, no scraping, no anti-bot evasion: these are lookup services built to be queried by machines.

### What this returns

Each domain produces one combined record:

```json
{
  "domain": "github.com",
  "dns": {
    "records": { "A": [...], "MX": [...], "NS": [...], "TXT": [...] },
    "has_a_or_aaaa": true,
    "resolved_via": "google"
  },
  "rdap": {
    "found": true,
    "registered_at": "2007-10-09T18:20:50Z",
    "expires_at": "2026-10-09T18:20:50Z",
    "nameservers": ["NS-1283.AWSDNS-32.ORG", "..."],
    "entities": [{"roles": ["registrar"], "name": "MarkMonitor Inc."}]
  }
}
```

### Why DoH and RDAP instead of a WHOIS scrape

Legacy WHOIS is unstructured text with a different format per registry, and its port-43 protocol is not reachable over plain HTTP at all. RDAP is its replacement: same information, structured JSON, one bootstrap redirector (`rdap.org`) that finds the right registry for any TLD. DNS-over-HTTPS is the same idea for name resolution — plain HTTP GET, clean JSON, no resolver configuration needed.

**Two providers with automatic fallover.** DNS queries try Google (`dns.google`) first, then Cloudflare (`cloudflare-dns.com`) if that fails — both are documented public services with no rate-limit surprises in normal use.

### A note on "not found"

`rdap.org` closes the connection outright for domains with no RDAP record, rather than returning a clean 404. This Actor treats that as a fast, expected outcome (one quick retry, then a clear `found: false`) rather than retrying it with full backoff — a domain being unregistered, or served by a registry not yet in the bootstrap list, is normal, not an error.

### Personal data is redacted, by design

Since GDPR, virtually every registry redacts registrant personal information from RDAP responses. `entities` in the output typically holds only the registrar — this is the registry's own privacy policy, not a limitation of this Actor, and it is also why this target is compliance-safe: no personal data is being extracted from a service that intended to protect it.

### Input

| Field | Type | Notes |
|---|---|---|
| `domains` | array | One or more domains. |
| `recordTypes` | array | DNS types to fetch. Default: A, AAAA, MX, NS, TXT. |
| `includeDns` | boolean | Toggle DNS lookups. |
| `includeRdap` | boolean | Toggle RDAP lookups. |

### Known limits

- **RDAP coverage is not universal.** Some ccTLD registries do not yet participate in the RDAP bootstrap; those domains return `rdap.found: false` even when registered. DNS results are unaffected and always attempted.
- **No historical data.** This is a live lookup, not a WHOIS history service — each run reflects the current state only.
- **No personal registrant data.** By registry policy, not by omission — see above.

### Local development

```bash
pip install -r requirements.txt
python test_local.py github.com apify.com --out sample_output.json
python test_local.py example.com --record-types A MX TXT
```

`sample_output.json` in this folder is real output from a live run, kept so the schema can be reviewed without running anything.

# Actor input Schema

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

One or more domains to look up.

## `recordTypes` (type: `array`):

Which DNS record types to fetch. Defaults to A, AAAA, MX, NS, TXT. Supported: A, AAAA, CNAME, MX, NS, TXT, SOA, PTR, SRV, CAA.

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

Fetch DNS records via DNS-over-HTTPS.

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

Fetch registration data (registrar, dates, nameservers, status) via RDAP.

## Actor input object example

```json
{
  "domains": [
    "github.com",
    "apify.com"
  ],
  "recordTypes": [
    "A",
    "MX",
    "TXT"
  ],
  "includeDns": true,
  "includeRdap": true
}
```

# Actor output Schema

## `lookups` (type: `string`):

One row per domain: DNS answers grouped by record type, plus flattened RDAP registration data.

## `coverage` (type: `string`):

How many domains were requested versus resolved via RDAP, and why any failed.

# 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": [
        "github.com"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("axery/whois-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": ["github.com"] }

# Run the Actor and wait for it to finish
run = client.actor("axery/whois-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": [
    "github.com"
  ]
}' |
apify call axery/whois-dns-lookup --silent --output-dataset

```

## MCP server setup

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