# WHOIS API - Domain, DNS, IP, Subdomain, SSL Lookup (`nabeelbaghoor/whois-dns-ip-lookup-api`) Actor

Look up WHOIS registration and its history, live DNS records, IP geolocation and netblocks, subdomains, reverse IP, MX, NS and WHOIS, domain availability and reputation, website contacts and category, email verification and SSL certificates. Bring your own key.

- **URL**: https://apify.com/nabeelbaghoor/whois-dns-ip-lookup-api.md
- **Developed by:** [Nabeel Hassan](https://apify.com/nabeelbaghoor) (community)
- **Categories:** Developer tools, Business, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $8.00 / 1,000 record returneds

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?

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 API - Domain, DNS, IP, Subdomain, SSL Lookup

Sixteen domain and IP intelligence services behind one input: who registered a domain and when, how that registration has changed, what its DNS says today, which domains sit on an address, what a website is and who to contact there.

This actor calls a domain and IP intelligence API on your behalf and stores one row per record. Bring your own key: paste your account key into the input and the run uses your own plan and your own contract.

### What you get

- **WHOIS, now and over time.** The registrar, creation, update and expiry dates, status codes, name servers and registrant details. WHOIS history returns one row per recorded change, so you can see when a domain changed hands.
- **Reverse WHOIS.** Every domain whose registration details mention up to four terms you give, with up to four more terms excluded, over current records or over historical ones as well.
- **DNS as rows.** One row per live record with its type, name, TTL, address or target, SOA serial and admin, TXT strings and the raw text it was parsed from.
- **Reverse IP, MX and NS.** Every domain pointing at an address, using a mail server, or using a name server, each with the dates it was first and last seen and optionally whether it still resolves.
- **Subdomain enumeration.** Every subdomain the provider has observed, paged past the ten thousand record limit.
- **IP geolocation and netblocks.** Country, region, city, postcode, coordinates, timezone, ISP and connection type; and the registered range around it with its owner, description, admin and abuse contacts and autonomous system.
- **Domain availability and reputation.** Registered or not, checked against DNS or against the registry; and a reputation score with the specific checks that raised warnings.
- **Website contacts and category.** Company names, emails, phone numbers, postal addresses, social links, page title and description; and what the site is about with a confidence score.
- **Email verification.** Format, mail domain, mailbox over SMTP, accept-all, free provider and disposable checks, reduced to one honest deliverability verdict.
- **SSL certificates.** Subject, issuer, validity window, serial, signature algorithm, public key type and size, and every subject alternative name, optionally up the whole chain.

### Pay per result

You are charged per record, never per request, and only for rows that carry real data. A domain the provider has no record for is stored with the reason and costs nothing.

| Event | Price | What it covers |
| --- | --- | --- |
| Record returned | $0.008 | One WHOIS record, historical change, DNS record, geolocation, netblock, availability or reputation result, contact set, category, verified email or certificate |
| Discovered domain returned | $0.003 | One name from a reverse IP, MX, NS, WHOIS or subdomain lookup, with first and last seen dates |

### Quick start

1. Get an API key from the products page of your provider account.
2. Paste it into **API key**.
3. Leave **What this run does** on WHOIS and put one domain in **What to look up**.
4. Set **Maximum rows** to the most you want to pay for.
5. Run it.

### FAQ

#### What is a WHOIS API?

A WHOIS API returns the registration record behind a domain name: which registrar it is with, when it was created, last updated and when it expires, the status codes the registry has applied to it, its name servers, and whatever registrant contact details are public. This actor reads that record and fifteen related services from the same account, including the historical versions of the record and the reverse searches over it.

#### Can I find every domain a company owns?

Yes, two ways. Reverse WHOIS finds every domain whose registration details contain terms you give, such as a company name plus a country, with up to four terms included and four excluded, and it can search past registrations as well as current ones. Reverse NS and reverse MX find every domain using the same name servers or mail servers, which catches domains registered under privacy protection that a WHOIS search would miss.

#### How do I enumerate a domain's subdomains?

Subdomains mode returns every subdomain the provider has observed, with the dates each was first and last seen. A response is capped at ten thousand records, and this actor pages past that using the provider's own cursor, up to whatever row limit you set.

#### What is the difference between reverse IP and IP netblocks?

Reverse IP answers which domains point at one address. IP netblocks answers who owns the range that address sits in: the registered range, the network name, the organisation, the admin and abuse contacts and the autonomous system. One is about the sites, the other is about the network.

#### How reliable is the email verification?

It runs five checks and this actor turns them into one verdict rather than leaving you to combine them. The important subtlety is the accept-all check: on a domain that accepts mail to every address, a passing mailbox check proves nothing, so the verdict reads `accept-all domain, mailbox unconfirmed` instead of `deliverable`. A check the provider could not run comes back as null rather than as a false, so an unknown is never reported as a failure.

#### Why does a preview mode return a count and no rows?

WHOIS history and reverse WHOIS both default to a preview that reports how many records match without listing them. Preview costs one credit or none; buying the list costs considerably more. This actor keeps preview as the default so an exploratory run cannot spend fifty credits per domain by accident, stores the count as the reason on the row, and tells you which option to turn on.

#### My key works elsewhere but this run says it is refused. Why?

The provider gives three reasons for a refusal and any of them fits: the key is wrong, the credit balance is empty, or the address the request came from is not on the account's IP allowlist. The last one is the one that catches people running on a cloud platform, because the key is fine and only the address is wrong. The run passes the provider's own wording through rather than guessing which of the three it was.

#### Do all the services report an error the same way?

No, and this is worth knowing if you have written against this API yourself. The DNS service returns HTTP 200 with an error object in the body when the key is bad, while the WHOIS service returns 401 and the rest return 403; and the three families use three different error envelopes. A client that trusted the status line would report an empty result set for a dead key. This actor inspects every response body before treating it as data, so a refused key ends the run with an explanation rather than looking like a domain with no DNS.

#### What happens if my key is missing or rejected?

The run ends cleanly with the reason as its status message rather than failing with a stack trace. A missing key, an empty input, a key the provider will not accept and an exhausted balance are all treated as answers, not faults.

#### Is my API key stored anywhere?

No. It is read from the run input or from the `DATA_API_KEY` environment secret, used for that run's requests, and never written to the dataset or the log.

### Example output

```json
{
  "recordType": "whois",
  "requested": "google.com",
  "found": true,
  "domainName": "google.com",
  "registrarName": "MarkMonitor, Inc.",
  "registrarIanaId": 292,
  "whoisServer": "whois.markmonitor.com",
  "createdDate": "1997-09-15T07:00:00Z",
  "updatedDate": "2019-09-09T15:39:04Z",
  "expiresDate": "2028-09-13T07:00:00Z",
  "estimatedDomainAgeDays": 10582,
  "status": [
    "clientUpdateProhibited",
    "clientTransferProhibited",
    "clientDeleteProhibited"
  ],
  "nameServers": ["NS1.GOOGLE.COM", "NS2.GOOGLE.COM", "NS3.GOOGLE.COM", "NS4.GOOGLE.COM"],
  "registrantOrganization": "Google LLC",
  "registrantState": "CA",
  "registrantCountry": "US"
}
```

### Keyword map

WHOIS API, WHOIS lookup API, domain lookup API, WHOIS history API, reverse WHOIS API, DNS lookup API, DNS records API, subdomain finder API, subdomain enumeration, reverse IP lookup API, reverse MX lookup, reverse NS lookup, IP geolocation API, IP to location API, IP netblocks API, ASN lookup API, abuse contact lookup, domain availability API, domain reputation API, website contacts API, website categorization API, email verification API, email validation API, disposable email check, catch-all detection, SSL certificate lookup API, certificate transparency data, attack surface discovery, domain monitoring, threat intelligence enrichment

# Actor input Schema

## `mode` (type: `string`):

A run answers one question with one of the provider's services. Each service has its own credit cost on your account, so a run reads one rather than all of them. Fields belonging to another mode are ignored rather than causing an error.

## `apiKey` (type: `string`):

Your own account's API key, from the products page of your provider account. Bring your own key: nothing is shared between runs and the key is never written to the dataset or the log. If your account has an IP allowlist turned on, this run's address has to be on it, because the provider refuses a key from an unlisted address exactly as if the key were wrong.

## `terms` (type: `array`):

One per line. A domain name for WHOIS, WHOIS history, DNS, subdomains, availability, reputation, contacts, categorisation and certificates. An IP address for reverse IP, geolocation and netblocks. A mail server host name for reverse MX and a name server host name for reverse NS. An email address for verification. The WHOIS service also accepts an IP address or an email address, and netblocks also accepts an organisation name or an autonomous system number.

## `dnsTypes` (type: `array`):

Which DNS record types to read, used by DNS mode. Leave empty for every type the provider holds. Subdomains have to be queried on their own, so read \_dmarc.example.com rather than expecting a DMARC record under example.com.

## `whoisProtocol` (type: `string`):

Which protocol to read a registration over, used by WHOIS mode. Auto picks whichever answers better for the top level domain and is right for almost every run. RDAP is the structured successor to WHOIS but is not supported for every top level domain.

## `preferFresh` (type: `boolean`):

Ask the provider for a newer record than the one it has cached. Slower, and worth it when you are watching a registration change rather than reading it once.

## `ignoreRawText` (type: `boolean`):

Strip the unparsed registry text out of each WHOIS row. The parsed fields are unaffected, and rows get much smaller.

## `purchaseHistory` (type: `boolean`):

WHOIS history mode defaults to preview, which reports how many historical records exist for one credit and lists none of them. Turn this on to store the records themselves, which the provider charges 50 credits for per domain.

## `skipLiveWhois` (type: `boolean`):

WHOIS history mode normally adds today's record to the history, which needs a live query and slows the run. Turning this on keeps the run fast, at the cost of the most recent record when nothing is cached from the last day.

## `sinceDate` (type: `string`):

Only historical records the provider discovered on or after this date, written as YYYY-MM-DD. This is the field to filter on when watching for daily changes, because it uses the date the change was detected rather than the date it happened. For example 2026-01-01.

## `reverseWhoisInclude` (type: `array`):

Reverse WHOIS mode only. Terms that must all appear somewhere in a domain's WHOIS details, one per line, matched without regard to case. Registrant name, organisation, email address, street, city and country all count. The provider allows at most four.

## `reverseWhoisExclude` (type: `array`):

Reverse WHOIS mode only. Terms that must appear in none of a domain's WHOIS details, one per line. The provider allows at most four.

## `searchHistoricWhois` (type: `boolean`):

Reverse WHOIS mode only. Search past registrations as well as current ones, which finds domains an owner has since transferred or let lapse.

## `purchaseReverseWhois` (type: `boolean`):

Reverse WHOIS mode defaults to preview, which reports how many domains match without listing them and costs no credits. Turn this on to store the list itself.

## `createdDateFrom` (type: `string`):

Only domains created on or after this date, written as YYYY-MM-DD. Used by WHOIS history and reverse WHOIS. For example 2024-01-01.

## `createdDateTo` (type: `string`):

Only domains created on or before this date, written as YYYY-MM-DD. For example 2026-01-01.

## `updatedDateFrom` (type: `string`):

Only domains whose registration was updated on or after this date, written as YYYY-MM-DD. For example 2025-01-01.

## `updatedDateTo` (type: `string`):

Only domains whose registration was updated on or before this date, written as YYYY-MM-DD. For example 2026-01-01.

## `expiredDateFrom` (type: `string`):

Only domains expiring on or after this date, written as YYYY-MM-DD. Pairing this with an expiry cutoff is how you build a list of domains about to lapse. For example 2026-01-01.

## `expiredDateTo` (type: `string`):

Only domains expiring on or before this date, written as YYYY-MM-DD. For example 2026-12-31.

## `includeDnsChecks` (type: `boolean`):

Reverse IP, MX and NS modes only. Adds two DNS checks per result: whether the record came from a wildcard, and whether the domain still resolves. Slower, and the provider charges 7 credits per request instead of 5.

## `includeRelatedDomains` (type: `boolean`):

IP geolocation mode only. Adds up to five domains hosted on the address. Use reverse IP mode instead when you want all of them rather than a sample.

## `netblockMask` (type: `integer`):

IP netblocks mode only. Look up the range containing an address at this prefix length, 0 to 32 for IPv4 and up to 128 for IPv6. Leave empty for the most specific range the provider holds.

## `accurateAvailability` (type: `boolean`):

Domain availability mode only. Checks the registry as well as DNS, which is slower and more accurate. A domain can resolve without being registered, and can be registered without resolving, so this is the setting that matters when the answer decides a purchase.

## `fullReputationScan` (type: `boolean`):

Domain reputation mode only. Runs every test rather than the four in the fast scan, which are the domain status, malware databases, certificate validity and the WHOIS record. The provider charges 3 credits instead of 1.

## `freshWebsiteContacts` (type: `boolean`):

Website contacts mode only. Fetches the contacts from the live site rather than from the provider's cache. Slower, and the right choice when a site has recently changed.

## `minConfidence` (type: `number`):

Website categorisation mode only. Drop predicted categories below this confidence, between 0 and 1. The provider's own default is 0.55; raising it returns fewer categories and fewer false positives.

## `checkDns` (type: `boolean`):

Email verification mode only. Confirms the part after the at sign is a real mail domain.

## `checkSmtp` (type: `boolean`):

Email verification mode only. Opens an SMTP conversation with the mail server to see whether the mailbox exists. This is the slowest check and the one that decides deliverability, and some providers refuse to answer it at all.

## `checkCatchAll` (type: `boolean`):

Email verification mode only. Detects a domain that accepts mail to every address. Worth keeping on, because on an accept-all domain a passing mailbox check is not evidence the mailbox exists.

## `checkFreeProvider` (type: `boolean`):

Email verification mode only. Flags addresses at free consumer providers rather than a company's own domain.

## `checkDisposable` (type: `boolean`):

Email verification mode only. Flags throwaway addresses from temporary mail services.

## `includeCertificateChain` (type: `boolean`):

SSL certificates mode only. Returns every certificate from the end-user one up to the root, rather than only the one presented for the domain.

## `freshCertificates` (type: `boolean`):

SSL certificates mode only. Reads the certificate from the host now rather than from the provider's cache.

## `maxResults` (type: `integer`):

The most rows this run may store, and so the most it can charge for. A reverse IP or subdomain lookup on a large host can return tens of thousands of names, so this is the cap that keeps a run predictable.

## `requestsPerMinute` (type: `integer`):

How fast this run calls the provider. Several of these services allow 30 requests a second, so the default is well inside that; lower it if your plan is throttled more tightly.

## Actor input object example

```json
{
  "mode": "whois",
  "terms": [
    "google.com"
  ],
  "whoisProtocol": "auto",
  "preferFresh": false,
  "ignoreRawText": false,
  "purchaseHistory": false,
  "skipLiveWhois": false,
  "searchHistoricWhois": false,
  "purchaseReverseWhois": false,
  "includeDnsChecks": false,
  "includeRelatedDomains": false,
  "accurateAvailability": false,
  "fullReputationScan": false,
  "freshWebsiteContacts": false,
  "checkDns": true,
  "checkSmtp": true,
  "checkCatchAll": true,
  "checkFreeProvider": true,
  "checkDisposable": true,
  "includeCertificateChain": false,
  "freshCertificates": false,
  "maxResults": 100,
  "requestsPerMinute": 120
}
```

# Actor output Schema

## `records` (type: `string`):

One row per record, alongside the domain, IP address, host name, email address or search term that produced it.

# 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 = {
    "terms": [
        "google.com"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("nabeelbaghoor/whois-dns-ip-lookup-api").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 = { "terms": ["google.com"] }

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

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,nabeelbaghoor/whois-dns-ip-lookup-api"
        }
    }
}

```

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/wDv8vWzc9YbtQAjCq/builds/80yWRbyvmqvJC3REW/openapi.json
