# Bulk WHOIS Domain Lookup: Age, Expiry, Registrar, DNS & SSL (`fguiraud/bulk-whois-domain-lookup`) Actor

Bulk WHOIS lookup for any list of domains or a Google Sheet: registrar, creation date, domain age, expiry date, registered or available, nameservers, DNS, MX, email provider, SPF/DMARC and SSL expiry. One flat row per domain, ready for Excel. RDAP + WHOIS for 1,000+ TLDs.

- **URL**: https://apify.com/fguiraud/bulk-whois-domain-lookup.md
- **Developed by:** [Fernando Guiraud](https://apify.com/fguiraud) (community)
- **Categories:** Lead generation, Developer tools, SEO tools
- **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 looked ups

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

### What does Bulk WHOIS Domain Lookup do?

**Bulk WHOIS Domain Lookup** checks any list of domains and returns **one flat row per domain**: **registrar, creation date, domain age, expiry date, days until expiry, whether the domain is registered or available**, nameservers, DNSSEC, IP addresses, **MX records and email provider**, SPF and DMARC, plus the **SSL certificate issuer and expiry**.

Paste domains, website URLs or a **Google Sheets link**, and download the result as **Excel, CSV or JSON**. It uses the official **RDAP** registries, with an automatic **classic WHOIS fallback** for ccTLDs such as .io, .co, .de, .it, .jp, .me, .mx, .se and .eu. No API key, no rate limits to manage, and you **pay only for domains that return data**.

It runs on the Apify platform, so you also get an API, **scheduling** (e.g. a weekly expiry check), integrations (Google Sheets, Make, Zapier, n8n, Slack) and access for **AI agents through the [Apify MCP server](https://mcp.apify.com)**.

### Why use it?

- 📅 **Domain expiry monitoring**: schedule it weekly for your own or your clients' domains and get an `alerts` entry when a domain or SSL certificate expires within 30 days.
- 🧮 **Domain age checks**: sort leads, backlinks or marketplaces by `domainAgeYears`. Old domains are a trust signal, and brand-new ones are a common fraud signal.
- 🛒 **Domain investing and availability**: `registered: false` shows domains the registry reports as not registered.
- 📧 **Email setup at a glance**: `emailProvider` (Google Workspace, Microsoft 365, Zoho…) and `dmarcPolicy` for every domain, which is useful for sales prospecting and deliverability audits.
- 🔎 **Due diligence**: registrar, creation date and nameservers for any list of domains in one table.

### How to do a bulk WHOIS lookup

1. Click **Try for free**.
2. Paste your domains (one per line), or put a Google Sheets / CSV link in **Domain list URL**.
3. Click **Start**. A thousand domains take a few minutes.
4. Download the table as **Excel or CSV**, or connect it to Google Sheets.

### Input

| Field | Description | Default |
|---|---|---|
| `domains` | Domains or URLs; each registrable domain is looked up once | `domains` or `domainsFromUrl` required |
| `domainsFromUrl` | TXT/CSV file or Google Sheet (shared as "Anyone with the link") with one domain per row; headers and other columns are ignored | - |
| `includeSsl` | Also return SSL certificate issuer and expiry | `true` |
| `alertDaysBeforeExpiry` | Alert when the domain or certificate expires within N days | `30` |

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

### Output

One row per domain. You can download the dataset in various formats such as JSON, HTML, CSV, or Excel.

```json
{
  "domain": "wordpress.org",
  "status": "ok",
  "registered": true,
  "registrar": "MarkMonitor Inc.",
  "createdDate": "2003-03-28T01:07:35.665Z",
  "expiryDate": "2035-03-28T01:07:35.665Z",
  "domainAgeDays": 8581,
  "domainAgeYears": 23.5,
  "daysUntilExpiry": 3106,
  "registrationStatus": ["client delete prohibited", "client transfer prohibited"],
  "nameservers": ["ns1.wordpress.org", "ns2.wordpress.org"],
  "dnssec": false,
  "whoisSource": "rdap",
  "ipAddresses": ["66.6.42.252"],
  "mxRecords": ["10 smtp1-dca.wordpress.org"],
  "emailProvider": "Self-hosted / other",
  "dmarcPolicy": "reject",
  "sslValid": true,
  "sslIssuer": "Let's Encrypt",
  "sslExpiryDate": "2026-12-22T19:43:57+00:00",
  "sslDaysUntilExpiry": 89,
  "alerts": []
}
```

### Data fields

| Field | Description |
|---|---|
| `registered` | `true` registered, `false` not registered (available), `null` unknown |
| `registrar` | Registrar name |
| `createdDate` / `expiryDate` / `updatedDate` | Registration dates (ISO 8601) |
| `domainAgeDays` / `domainAgeYears` | Age of the domain |
| `daysUntilExpiry` | Days until the registration expires |
| `nameservers`, `dnssec` | DNS delegation |
| `ipAddresses`, `mxRecords`, `emailProvider`, `spf`, `dmarcPolicy` | DNS and email setup |
| `sslIssuer`, `sslExpiryDate`, `sslDaysUntilExpiry` | SSL certificate |
| `alerts` | Domain/SSL expiring soon, invalid certificate, missing DMARC |

### How much does a bulk WHOIS lookup cost?

| Event | Price |
|---|---|
| Run start (per GB of memory, default 512 MB) | $0.001 |
| Domain looked up | **$0.002** (about $2 per 1,000 domains) |

Domains that return no data at all are **not billed** (a domain that is not registered counts as a result: `registered: false`). Set **Max cost per run** and the Actor stops cleanly at that limit.

### Use it with AI agents (MCP)

Add `https://mcp.apify.com?tools=fguiraud/bulk-whois-domain-lookup` to Claude, Cursor or any MCP client and ask: *"When do these 20 domains expire, and which ones are older than 10 years?"*

### Need more than WHOIS?

For the **technology stack** (CMS, analytics, ecommerce, 7,000+ technologies), **SEO audit**, hosting provider and security grade, use [Tech Stack Detector & WHOIS, SSL Checker](https://apify.com/fguiraud/website-tech-dns-whois-ssl), which includes everything here plus much more.

### FAQ and limitations

- **Why are some fields empty for my country's domain?** Some ccTLD registries publish very little data (for example no registrar or no dates). The Actor returns whatever the registry provides.
- **Is the owner's name or email included?** No. Since GDPR, registries redact personal contact data, and this Actor does not collect it.
- **Is `registered: false` a guarantee that I can buy the domain?** No. It reflects the registry's answer at that moment; premium or reserved names may still be unavailable.
- Found a problem or need a feature? Open an issue on the **Issues** tab. Replies within 48 hours.

# Actor input Schema

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

Domains (example.com) or website URLs (https://www.example.com/page). Each registrable domain is looked up once. Optional if you use 'Domain list URL' below.

## `domainsFromUrl` (type: `string`):

Link to a plain-text or CSV file with one domain/URL per row, or a Google Sheets link shared as "Anyone with the link". In each row the first cell that looks like a domain or URL is used; headers and other columns are ignored.

## `includeSsl` (type: `boolean`):

Also check the website's SSL certificate (issuer, expiry date, days left). Same price.

## `alertDaysBeforeExpiry` (type: `integer`):

Add an alert when the domain registration or the SSL certificate expires within this many days.

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

How many domains are looked up at the same time.

## `failOnError` (type: `boolean`):

Mark the run as FAILED when any domain returns no data at all. Useful for monitoring pipelines.

## Actor input object example

```json
{
  "domains": [
    "apify.com",
    "wordpress.org",
    "bbc.co.uk"
  ],
  "includeSsl": true,
  "alertDaysBeforeExpiry": 30,
  "maxConcurrency": 10,
  "failOnError": false
}
```

# 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",
        "wordpress.org",
        "bbc.co.uk"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("fguiraud/bulk-whois-domain-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",
        "wordpress.org",
        "bbc.co.uk",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("fguiraud/bulk-whois-domain-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",
    "wordpress.org",
    "bbc.co.uk"
  ]
}' |
apify call fguiraud/bulk-whois-domain-lookup --silent --output-dataset

```

## MCP server setup

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