WHOIS Lookup
/api/whois?q={domain_or_ip}
No Auth RequiredWHOIS data is one of those things that should be simple to get but never is. Most WHOIS APIs charge money, rate limit you into oblivion, or return raw text that looks like it was formatted by a fax machine in 1997.
This endpoint gives you clean, structured JSON. Pass a domain name and get registration details. Pass an IP and get network allocation info. No parsing required. No regex nightmares.
Under the hood, it talks to RDAP servers (the modern replacement for WHOIS). Same data, better format, fewer headaches.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
q | string | Yes | Domain name (e.g. google.com) or IP address (e.g. 8.8.8.8) |
Response Fields (Domain Lookup)
When you pass a domain name, you get registration and registrar info:
| Field | Type | Description |
|---|---|---|
Domain | string | The domain name queried |
Status | string | Domain status codes (e.g. "clientTransferProhibited") |
Registered | string | Registration date |
Expires | string | Expiration date |
Last Updated | string | Last modification date |
Nameservers | string | Authoritative nameservers (comma separated) |
Registrar | string | Registrar name |
Registrar IANA | string | Registrar's IANA ID number |
Registrar URL | string | Registrar's website |
Registrant Org | string | Organization that registered the domain (if public) |
Registrant Country | string | Registrant's country code |
Response Fields (IP Lookup)
When you pass an IP address, you get network allocation info:
| Field | Type | Description |
|---|---|---|
Name | string | Network name |
Handle | string | Registry handle/identifier |
Start IP | string | First IP in the allocated block |
End IP | string | Last IP in the allocated block |
Country | string | Country code of the allocation |
IP Version | string | "v4" or "v6" |
Type | string | Allocation type (e.g. "ALLOCATION", "ASSIGNMENT") |
CIDR | string | CIDR notation of the block |
Org | string | Organization holding the allocation |
Abuse Email | string | Abuse contact email for the network |
Example Request
curl
# Domain lookup
curl "https://whatismyip.technology/api/whois?q=google.com"
# IP lookup
curl "https://whatismyip.technology/api/whois?q=8.8.8.8"
Python
import requests
# Domain lookup
response = requests.get(
"https://whatismyip.technology/api/whois",
params={"q": "google.com"}
)
data = response.json()
print(f"Registrar: {data['data']['Registrar']}")
print(f"Expires: {data['data']['Expires']}")
print(f"Nameservers: {data['data']['Nameservers']}")
JavaScript
// Domain lookup
const response = await fetch(
"https://whatismyip.technology/api/whois?q=google.com"
);
const { data } = await response.json();
console.log(`Registrar: ${data.Registrar}`);
console.log(`Expires: ${data.Expires}`);
console.log(`Nameservers: ${data.Nameservers}`);
Example Response (Domain)
{
"data": {
"Domain": "google.com",
"Status": "clientDeleteProhibited, clientTransferProhibited, clientUpdateProhibited, serverDeleteProhibited, serverTransferProhibited, serverUpdateProhibited",
"Registered": "1997-09-15T04:00:00Z",
"Expires": "2028-09-14T04:00:00Z",
"Last Updated": "2019-09-09T15:39:04Z",
"Nameservers": "ns1.google.com, ns2.google.com, ns3.google.com, ns4.google.com",
"Registrar": "MarkMonitor Inc.",
"Registrar IANA": "292",
"Registrar URL": "http://www.markmonitor.com",
"Registrant Org": "Google LLC",
"Registrant Country": "US"
},
"partial": false
}
Example Response (IP)
{
"data": {
"Name": "GOGL",
"Handle": "NET-8-8-8-0-2",
"Start IP": "8.8.8.0",
"End IP": "8.8.8.255",
"Country": "US",
"IP Version": "v4",
"Type": "ALLOCATION",
"CIDR": "8.8.8.0/24",
"Org": "Google LLC",
"Abuse Email": "[email protected]"
},
"partial": false
}
The partial Flag
This is the interesting part. The WHOIS endpoint never throws errors. If the upstream RDAP servers are down, slow, or returning nonsense, you still get a 200 response. But the partial field will be true, and the data object might be empty or incomplete.
Why? Because partial data is better than no data. If you’re building a UI that shows WHOIS info, you can still render whatever fields came back instead of showing an error screen.
Check the partial field. If it’s true, let your users know the data might be incomplete.
Runtime and Caching
Runs on the Edge runtime with a 30-second execution limit. RDAP servers can be slow, especially for obscure TLDs or IP ranges managed by smaller registries.
Successful responses are cached for 5 minutes. If the response is partial (because upstream failed), it uses no-store so the next request tries fresh. Smart. You don’t want to cache bad data.
Upstream Architecture
The endpoint has a two-tier fallback system:
- Primary: rdap.org with a 12-second timeout
- Fallback: rdap.iana.org with a 10-second timeout
If the primary times out or errors, it tries the fallback. If both fail, you get {data: {}, partial: true}. No 500 errors. No stack traces. Just a polite JSON object admitting it couldn’t get the full picture.
Notes and Edge Cases
Privacy-protected domains will have limited registrant info. Most registrars now redact personal details by default (thanks, GDPR). You’ll still get the registrar, dates, and nameservers, but Registrant Org and Registrant Country might be empty.
New TLDs (.xyz, .io, .dev, etc.) generally have good RDAP support. Very old or country-code TLDs (.uk, .de, .jp) can be hit or miss. Some country registries don’t support RDAP at all, which means you might get partial results.
Subdomains won’t work. Pass google.com, not mail.google.com. The RDAP protocol works at the registered domain level.
The q parameter accepts both domains and IPs. The endpoint figures out which one you passed and queries the right RDAP server accordingly. You don’t need to tell it.