BULK WHOIS API

Bulk WHOIS API with Normalized JSON Results

Run high-volume WHOIS and RDAP lookups for domain lists using a fast JSON API.

Start with 1,000 free requests. No credit card required.

cURL
curl -s "https://whoisjson.com/api/v1/whois?domain=example.com" \
  -H "Authorization: TOKEN=YOUR_API_KEY"
Scope

What this API does / doesn't do

Use this section to decide whether Bulk WHOIS fits your workflow, or whether another WhoisJSON endpoint is a better match.

What this Bulk WHOIS API does

  • Runs WHOIS and RDAP lookups for domain lists through one JSON API.
  • Returns normalized fields such as registrar, creation date, expiration date, statuses, nameservers, and source.
  • Lets you process high-volume domain datasets with documented quotas, rate limits, caching, and standard HTTP errors.
  • Works for enrichment, compliance checks, portfolio audits, security pipelines, and monitoring preparation.

What this API is not for

  • It is not a reverse WHOIS search by owner, email, company, or registrant identity.
  • It is not a historical WHOIS ownership database or deleted-domain archive.
  • It is not the dedicated domain availability endpoint; use the Domain Availability API when you only need available, taken, or unknown.
  • It is not a raw WHOIS scraping tool; responses are normalized for API workflows.
Pricing

Volume Pricing

Fixed Quota — pay for what you use

PlanPrice / moRequests / moCost per 1k
Basic$01,000$0
Pro$1030,000$0.33
Ultra$30150,000$0.20
Scale$501,000,000$0.05

Unlimited Plans — no fixed monthly quota, limited only by rate limit

PlanPrice / moRate LimitCost / 1k at max *
Mega$80100 req/min~$0.023
Giga$120200 req/min~$0.017
Tera$200300 req/min~$0.019
Atlas$600900 req/min~$0.019

* Cost/1k at continuous full-rate usage — actual cost is lower at partial utilization.

Need a free tier first? Get 1,000 requests/month at no cost →

Limits

Rate Limits by Plan

Fixed Quota Plans

PlanMonthly QuotaRate LimitCache TTL
Basic1,000 req/mo20 req/min3 hours
Pro30,000 req/mo40 req/min3 hours
Ultra150,000 req/mo60 req/min3 hours
Scale1,000,000 req/mo100 req/min3 hours

Unlimited Plans

PlanMax req / month *Rate LimitCache TTL
Mega~3,456,000100 req/min3 hours
Giga~6,912,000200 req/min3 hours
Tera~10,368,000300 req/min3 hours
Atlas~31,104,000900 req/min3 hours

* Max at continuous full-rate usage. Add_forceRefresh=1 to bypass cache (costs 2× credits). All endpoints share the same quota. Full plan details →

Why WhoisJSON

Built for Pipelines, Not Just One-Off Lookups

Consistent schema across 1,500+ TLDs

Every response uses the same field names — registrar, created, expires, status, nameserver — regardless of whether the data came from a legacy WHOIS server or an RDAP endpoint. No per-TLD parsing logic, no schema branching in your pipeline. Thesource field tells you which protocol was used; RDAP responses include additional enriched fields (age,expiration.daysLeft,nsAnalysis) that your code can use when present.

Predictable rate limits, standard back-off

Rate limits are documented, fixed per plan, and enforced on a rolling 60-second window. A429 response means slow down — not that your key is revoked. Implement exponential back-off and your pipeline recovers automatically. TheRemaining-Requests response header is present in every reply so you can pause before hitting the monthly cap rather than discovering it mid-run.

One key for the full domain intelligence stack

The same API token also gives you access to DNS record lookups, SSL certificate checks, real-time availability, subdomain discovery, and change monitoring. One HTTP client, one auth header, six tools. If your pipeline needs WHOIS + DNS + SSL in a single pass, you don't sign up anywhere else.

Caching that works with bulk workloads

Responses are cached for 3 hours, which matters when you're running the same domain list more than once (monitoring sweeps, reprocessing failures). Cache hits don't count against your monthly quota. When freshness is required, add_forceRefresh=1 to any request — it bypasses the cache and costs 2× credits, so use it only where it changes the outcome.

Node.js

Bulk WHOIS in Node.js

Sequential processing with rate-limit pacing and exponential back-off on 429.

bulk-whois.js
const API_KEY    = 'YOUR_API_KEY';
const RATE_LIMIT = 40; // req/min — Pro:40, Ultra:60, Scale/Mega:100, Atlas:900

const domains = ['example.com', 'github.com', 'google.com'];

const sleep = (ms) => new Promise((r) => setTimeout(r, ms));

async function whoisLookup(domain, retries = 3) {
  const url = `https://whoisjson.com/api/v1/whois?domain=${encodeURIComponent(domain)}`;

  for (let attempt = 1; attempt <= retries; attempt++) {
    const res = await fetch(url, {
      headers: { Authorization: `TOKEN=${API_KEY}` },
    });

    if (res.status === 429) {        // rate-limited — back off
      await sleep(2 ** attempt * 1000);
      continue;
    }
    if (!res.ok) throw new Error(`HTTP ${res.status} for ${domain}`);
    return res.json();
  }
  throw new Error(`${domain}: exceeded retry limit`);
}

async function bulkWhois(domains) {
  const results = [];
  const interval = 60_000 / RATE_LIMIT; // ms between requests

  for (const domain of domains) {
    const t0 = Date.now();

    try {
      const data = await whoisLookup(domain);
      results.push({ domain, data });
      console.log(`[ok] ${domain}  registered=${data.registered}`);
    } catch (err) {
      results.push({ domain, error: err.message });
      console.error(`[err] ${err.message}`);
    }

    const elapsed = Date.now() - t0;
    if (elapsed < interval) await sleep(interval - elapsed);
  }

  return results;
}

bulkWhois(domains).then((r) =>
  console.log(`Done: ${r.length} lookups`)
);
Python

WHOIS Lookups in Python

Query the WHOIS endpoint for a domain list, keep the output normalized, and respect rate limits between lookups.

bulk_whois.py
import requests
import time
from urllib.parse import urlencode

API_KEY     = 'YOUR_API_KEY'
RATE_LIMIT  = 40   # req/min — Pro:40, Ultra:60, Scale/Mega:100, Atlas:900

session = requests.Session()
session.headers['Authorization'] = f'TOKEN={API_KEY}'


def whois_lookup(domain: str, retries: int = 3) -> dict:
    query = urlencode({'domain': domain})
    url = f'https://whoisjson.com/api/v1/whois?{query}'

    for attempt in range(1, retries + 1):
        response = session.get(url, timeout=15)

        if response.status_code == 429:  # WHOIS rate limit: back off and retry
            time.sleep(2 ** attempt)
            continue

        response.raise_for_status()
        return response.json()

    raise RuntimeError(f'{domain}: exceeded retry limit')


def bulk_whois(domains: list[str]) -> list[dict]:
    results  = []
    interval = 60.0 / RATE_LIMIT  # seconds between requests

    for domain in domains:
        started_at = time.monotonic()

        try:
            data = whois_lookup(domain)
            results.append({
                'domain': domain,
                'registered': data.get('registered'),
                'registrar': data.get('registrar'),
                'created': data.get('created'),
                'expires': data.get('expires'),
                'source': data.get('source'),  # WHOIS or RDAP
            })
            print(f'[ok]  {domain}  source={data.get("source")}')
        except requests.RequestException as exc:
            results.append({'domain': domain, 'error': str(exc)})
            print(f'[err] {domain}: {exc}')

        elapsed = time.monotonic() - started_at
        if elapsed < interval:
            time.sleep(interval - elapsed)

    return results


if __name__ == '__main__':
    domains = ['example.com', 'github.com', 'google.com']
    results = bulk_whois(domains)
    print(f'Done: {len(results)} lookups')
Response Format

Annotated JSON Response

Same normalized schema for every TLD and registrar. Thesource field indicates whether data came from WHOIS or RDAP.

GET /api/v1/whois?domain=example.com → 200 OK
{
  "name": "example.com",           // queried domain, normalized
  "registered": true,               // false when domain is unregistered
  "source": "rdap",                 // "whois" | "rdap"

  "created": "1995-08-14T04:00:00Z",
  "changed": "2023-08-14T07:01:31Z",
  "expires": "2024-08-13T04:00:00Z",

  "age": {                          // only when source = "rdap"
    "days": 10484,
    "months": 345,
    "years": 28,
    "isNewlyRegistered": false,     // true when created <= 30 days ago
    "isYoung": false                // true when created <= 365 days ago
  },

  "expiration": {                   // only when source = "rdap"
    "daysLeft": 109,
    "isExpiringSoon": false,
    "isExpired": false
  },

  "status": [                       // EPP status codes
    "clientDeleteProhibited",
    "clientTransferProhibited"
  ],

  "nameserver": [
    "a.iana-servers.net",
    "b.iana-servers.net"
  ],

  "registrar": {
    "name": "ICANN",
    "url": "https://www.icann.org"
  },

  "contacts": {                     // null when privacy-shielded
    "owner": [{ "name": "...", "email": "...", "country": "..." }],
    "admin":  [{ "name": "...", "email": "..." }],
    "tech":   [{ "name": "...", "email": "..." }]
  },

  "dnssec": "signedDelegation",
  "parsedContacts": true,
  "whoisserver": "whois.iana.org"   // WHOIS server queried
}
Comparison

Provider Comparison

ProviderNormalized JSONMax Rate LimitPrice per 1kFree Tier
WhoisJSON✓ Yes900 req/min (Atlas)From $0.021,000 req/mo
WhoisXMLAPI✓ Yes~3,000 req/min30$ for 2k requests500 queries
Whoxy✓ Yes1,000 req/minFrom $0.40 / 1kPay-as-you-go
WhoisFreaks✓ Yes80 req/min (live)Credit-based500 credits

Data sourced from public pricing and documentation pages, April 2026. WhoisXMLAPI pricing requires login. WhoisFreaks uses a credit system — cost per request varies by endpoint. Verify current rates before choosing a provider.

FAQ

Bulk WHOIS API — Technical FAQ

Userequests.Session for connection reuse, call the/api/v1/whois endpoint for each domain, and pace requests according to your plan's rate limit. Implement exponential back-off when you receive a429. The example above sleeps60/RATE_LIMIT seconds between WHOIS lookups (1.5 s on Pro, 1 s on Ultra). For datasets over 1M, process in batches of ~10k and checkpoint to disk between batches.

Rate limits are per API key. Fixed Quota plans: 20 req/min (Basic), 40 req/min (Pro), 60 req/min (Ultra), 100 req/min (Scale). Unlimited plans: 100 req/min (Mega), 200 req/min (Giga), 300 req/min (Tera), 900 req/min (Atlas). Limits are enforced on a rolling 60-second window — exceeding the limit returns a429. Custom enterprise limits are available for Atlas-tier customers —contact support.

Over 1,500 TLDs including all major gTLDs (.com, .net, .org, .io) and country-code TLDs. For TLDs with RDAP support the response includes additional enriched fields (age,expiration,statusAnalysis,nsAnalysis). Thesource field in every response tells you which protocol was used. A small number of TLDs restrict automated queries — for those the API returns a structured error you can log and skip.

The API uses standard HTTP status codes:200 success,400 bad domain format,401 invalid API key,429 rate limit exceeded,5xx server error. On429, apply exponential back-off (see examples above). On5xx, retry after 2–5 seconds. TheRemaining-Requests response header tells you how many credits remain so you can pause before hitting the monthly cap.

JSON by default. Addformat=xml to receive XML instead. The schema is consistent across all TLDs and registrars — same field names whether the lookup hits a WHOIS server or an RDAP endpoint. See theAPI reference for the complete field list, or the annotated response above for the most common fields.

RDAP (Registration Data Access Protocol) is the modern replacement for WHOIS, with structured JSON at the protocol level. When a registry supports RDAP, WhoisJSON uses it automatically and returns additional fields:statusAnalysis (parsed EPP flags),nsAnalysis (nameserver infrastructure),age (days/months/years since registration,isNewlyRegistered,isYoung), andexpiration.daysLeft. Thesource field is always present so your pipeline can branch on data availability. For a deeper comparison seeWHOIS vs RDAP →

Start Processing Domains at Scale

1,000 free requests included. No credit card required. Upgrade when you need more.