WHOIS.CX
Lookup Plans API My Domains Monitors Scan Settings
Servers Rules TLD Limits Pricing
Users Tiers Tag Rules Pending Tags Notification Logs Raw Logs API Keys Settings
Notifications
No notifications

DomainIntelligence

Real-time WHOIS data extraction

⬡
Comparing domains...
Querying WHOIS servers...
Lookup Failed
AGE
—
EXPIRES
—
Created —
Expires —
Premium
CREATED
—
UPDATED
—
EXPIRES
—
REGISTRAR
Name —
IANA ID —
Abuse Contact —
NAMESERVERS
STATUS

                    
COMPARE

Choose Your Plan

Unlock advanced domain monitoring and intelligence features

API Documentation

Programmatic access to WHOIS/RDAP domain intelligence data.

Quickstart Endpoints WHOIS Lookup Account Info Rate Limits Authentication Error Codes Code Examples

Quickstart

No signup required. Copy-paste this and you're done:

Anonymous lookup
curl https://whois.cx/api/v1/whois/google.com

You'll get JSON with registrar, dates, nameservers, statuses, plus a _notice field nudging you to sign in for higher limits. Anonymous quota is per client IP — see Rate Limits.

Want higher limits? Generate an API key from My Settings and pass it in the X-API-Key header:

With an API key
curl -H "X-API-Key: whois_your_key" \
  https://whois.cx/api/v1/whois/google.com

IPs work too — try curl https://whois.cx/api/v1/whois/8.8.8.8 for IPv4/IPv6 RIR lookups.

Endpoints

Base URL: https://whois.cx/api/v1

Method Endpoint Description
GET /v1/whois/{domain} WHOIS/RDAP lookup for a domain
GET /v1/account Your API key info and usage stats

WHOIS Lookup

GET /v1/whois/{domain}

Look up WHOIS/RDAP registration data for a domain name or an IP address. The server picks the best protocol per TLD (RDAP / WHOIS / hybrid).

Parameters
ParameterTypeLocationDescription
domain string path Required. Domain name (e.g., google.com, example.co.uk) or IPv4/IPv6 address (e.g., 8.8.8.8, 2606:4700::). IP lookups walk the RIR referral chain (ARIN → RIPE/APNIC/LACNIC/AFRINIC).
Response
200 OK
{
  "domain": "google.com",
  "registrar": "MarkMonitor Inc.",
  "registrar_iana_id": "292",
  "registrar_abuse_email": "[email protected]",
  "creation_date": "1997-09-15T04:00:00Z",
  "updated_date": "2019-09-09T15:39:04Z",
  "expiry_date": "2028-09-14T04:00:00Z",
  "nameservers": [
    "ns1.google.com",
    "ns2.google.com",
    "ns3.google.com",
    "ns4.google.com"
  ],
  "status": [
    "client delete prohibited",
    "client transfer prohibited",
    "client update prohibited",
    "server delete prohibited",
    "server transfer prohibited",
    "server update prohibited"
  ],
  "dnssec": "unsigned",
  "_meta": {
    "protocol": "rdap",
    "duration_ms": 245
  }
}
Response Fields
FieldTypeDescription
domainstringQueried domain name
registrarstringDomain registrar name
registrar_iana_idstringRegistrar's IANA accreditation ID
registrar_abuse_emailstringRegistrar abuse contact email
creation_datestringDomain registration date (ISO 8601)
updated_datestringLast modification date (ISO 8601)
expiry_datestringDomain expiration date (ISO 8601)
nameserversarrayList of DNS nameservers
statusarrayDomain status codes (EPP format)
dnssecstringDNSSEC status
registrant_namestringRegistrant name/organization (if available)
registrant_countrystringRegistrant country (if available)
availablebooleanWhether the domain appears unregistered
_meta.protocolstringProtocol used: rdap, whois, or hybrid
_meta.duration_msintegerServer-side lookup duration in ms
_cachedbooleanPresent & true when the result came from Redis cache (no fresh registry hit). Omits _meta.
_noticestringOnly present on anonymous responses. A sign-in nudge with the current anon tier limits.
Note: Fields with no data are omitted. Only non-null, non-empty values are returned.

Account Info

GET /v1/account

Returns your current tier's limits and live usage. The response shape depends on whether you passed a key.

With API key
200 OK — tier: api_key
{
  "tier": "api_key",
  "key_name": "My App",
  "key_prefix": "whois_a1b2c3",
  "total_requests": 1542,
  "rate_limits": { "1m": 10, "1h": 200, "1d": 2000 },
  "rate_usage": {
    "1m": {"limit": 10,   "remaining": 7,    "reset": 1709740800, "requests": 3},
    "1h": {"limit": 200,  "remaining": 155,  "reset": 1709740800, "requests": 45},
    "1d": {"limit": 2000, "remaining": 1688, "reset": 1709769600, "requests": 312}
  },
  "created_at": "2025-01-15 10:30:00"
}
Anonymous (no key)
200 OK — tier: anonymous
{
  "tier": "anonymous",
  "rate_limits": { "1m": 3, "1h": 30, "1d": 100 },
  "rate_usage": {
    "1m": {"limit": 3,   "remaining": 2,  "reset": 1709740800, "requests": 1},
    "1h": {"limit": 30,  "remaining": 29, "reset": 1709740800, "requests": 1},
    "1d": {"limit": 100, "remaining": 99, "reset": 1709769600, "requests": 1}
  },
  "_notice": "You're using the anonymous tier (3/min, 30/hour, 100/day). Sign in at https://whois.cx to create an API key with higher limits."
}
Tip: Check for tier == "anonymous" or the presence of _notice to know which tier served your request.

Rate Limits

Two tiers are available: anonymous (no key, per-IP) and API key (per-key). Anonymous responses include a _notice field nudging you to sign in.

Anonymous tier — no key required
WindowDefault LimitDescription
Per Minute3Per client IP
Per Hour30Per client IP
Per Day100Per client IP
Sign in for higher limits. Create an API key from My Settings to move into the per-key tier below.
API key tier
WindowDefault LimitDescription
Per Minute10Short-burst protection
Per Hour200Medium-term limit
Per Day2,000Daily quota

Every response carries rate-limit headers so you can back off before you hit 429:

Response Headers
X-RateLimit-Limit: 3
X-RateLimit-Remaining: 2
X-RateLimit-Reset: 1709740800
Retry-After: 42            ← only on 429

When a window is exhausted you'll get a 429 Too Many Requests with the full window snapshot and (for anonymous callers) the _notice:

429 Too Many Requests
{
  "error": "Rate limit exceeded",
  "limits": {
    "1m": {"allowed": false, "limit": 3,   "remaining": 0, "reset": 1709740860, "requests": 3},
    "1h": {"allowed": true,  "limit": 30,  "remaining": 26, "reset": 1709743200, "requests": 4},
    "1d": {"allowed": true,  "limit": 100, "remaining": 96, "reset": 1709769600, "requests": 4}
  },
  "_notice": "You're using the anonymous tier (3/min, 30/hour, 100/day). Sign in at https://whois.cx to create an API key with higher limits."
}
Caching tip: Anonymous responses are served with Cache-Control: public, max-age=600. If you're hitting the same domain repeatedly from the same IP, a caching CDN or ETag-aware client can make those requests free.

Authentication

Authentication is optional. Use it to upgrade from the anonymous per-IP tier to the per-key tier with much higher limits.

Generate a key from My Settings, then pass it via the X-API-Key header (recommended) or the api_key query parameter:

Header (recommended)
curl -H "X-API-Key: whois_your_api_key_here" \
  https://whois.cx/api/v1/whois/google.com
Query parameter
curl "https://whois.cx/api/v1/whois/google.com?api_key=whois_your_api_key_here"
Security: Always prefer the header method. Don't embed keys in client-side code or URLs that can end up in browser history, proxy logs, or analytics.

Error Codes

StatusMeaningWhen
200OKSuccessful lookup
400Bad RequestInvalid domain or IP format
401UnauthorizedKey was sent but is invalid/expired — or no key sent while anonymous access is turned off
403ForbiddenThe public API is disabled entirely (api.enabled master toggle is off)
404Not FoundDomain not found / unsupported TLD
429Too Many RequestsPer-IP or per-key rate limit exhausted (see Rate Limits)
500Server ErrorInternal lookup failure

All error responses are JSON with at minimum an error string:

Error response
{"error": "Description of what went wrong"}

Code Examples

cURL
# Anonymous — works immediately, no signup
curl https://whois.cx/api/v1/whois/google.com

# IP lookup
curl https://whois.cx/api/v1/whois/8.8.8.8

# With an API key (higher limits)
curl -H "X-API-Key: whois_your_key" \
  https://whois.cx/api/v1/whois/google.com

# Check your tier's live usage
curl https://whois.cx/api/v1/account
Python
import requests

BASE_URL = "https://whois.cx/api/v1"
API_KEY = None  # set to "whois_your_key" for higher limits

headers = {"X-API-Key": API_KEY} if API_KEY else {}

r = requests.get(f"{BASE_URL}/whois/google.com", headers=headers)

if r.status_code == 429:
    retry = r.headers.get("Retry-After", "60")
    raise SystemExit(f"Rate limited — retry in {retry}s")

r.raise_for_status()
data = r.json()

print(f"Registrar:   {data.get('registrar')}")
print(f"Expires:     {data.get('expiry_date')}")
print(f"Nameservers: {', '.join(data.get('nameservers', []))}")

if "_notice" in data:
    print(f"\nNote: {data['_notice']}")
JavaScript (Node.js / Browser)
const BASE_URL = "https://whois.cx/api/v1";
const API_KEY  = null; // set to "whois_your_key" for higher limits

const headers = API_KEY ? { "X-API-Key": API_KEY } : {};
const res = await fetch(`${BASE_URL}/whois/google.com`, { headers });

if (res.status === 429) {
  const retry = res.headers.get("Retry-After") || "60";
  throw new Error(`Rate limited — retry in ${retry}s`);
}
if (!res.ok) throw new Error(`HTTP ${res.status}`);

const data = await res.json();
console.log(`Registrar:   ${data.registrar}`);
console.log(`Expires:     ${data.expiry_date}`);
console.log(`Nameservers: ${data.nameservers?.join(", ")}`);

if (data._notice) console.log("\nNote:", data._notice);
PHP
$baseUrl = "https://whois.cx/api/v1";
$apiKey  = null; // set to "whois_your_key" for higher limits

$ch = curl_init("$baseUrl/whois/google.com");
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => $apiKey ? ["X-API-Key: $apiKey"] : [],
]);
$body = curl_exec($ch);
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

if ($code === 429) {
    throw new RuntimeException("Rate limited");
}
if ($code !== 200) {
    throw new RuntimeException("HTTP $code");
}

$data = json_decode($body, true);

echo "Registrar:   " . ($data['registrar']   ?? 'N/A') . "\n";
echo "Expires:     " . ($data['expiry_date'] ?? 'N/A') . "\n";
echo "Nameservers: " . implode(', ', $data['nameservers'] ?? []) . "\n";

if (!empty($data['_notice'])) {
    echo "\nNote: " . $data['_notice'] . "\n";
}

Forgot Password

Enter your email address and we'll send you a link to reset your password.

Remember your password? Login

Login

Forgot password?
Don't have an account? Sign Up

Reset Password

Enter your new password below.

Sign Up

Already have an account? Login

Email Verification

Verifying your email...

✓

Email Verified!

Your email has been successfully verified.

✕

Verification Failed

Invalid or expired token.