The RDAP API for developers
Clean JSON for any domain across 1,200+ TLDs. We find the right server, manage rate limits, and pull registrar data when it lives there.
Example RDAP API response for google.com
{ "domain": "google.com", "unicode_name": null, "handle": "2138514_DOMAIN_COM-VRSN", "status": [ "client delete prohibited", "client transfer prohibited", "client update prohibited", "server delete prohibited", "server transfer prohibited", "server update prohibited" ], "registrar": { "name": "MarkMonitor Inc.", "iana_id": "292", "abuse_email": "[email protected]", "abuse_phone": "+12086851750", "url": "http://www.markmonitor.com" }, "dates": { "registered": "1997-09-15T04:00:00Z", "expires": "2028-09-14T04:00:00Z", "updated": "2019-09-09T15:39:04Z" }, "nameservers": [ "ns1.google.com", "ns2.google.com", "ns3.google.com", "ns4.google.com" ], "dnssec": false, "entities": {}}Normalized JSON
Every registry returns the same shape. No vcardArray decoding, no encoding guessing, no registry-specific quirks.
{ "nameservers": [- {- "ldhName": "GOOGLE.COM"- },- {- "ldhName": "ns1.google.com."- },- {- "ldhName": "ns1.hostingpalvelu.fi [31.217.192.71] [ok]"- },- {- "ldhName": "a.dns.gandi.net [technical check not done]"- } ] } { "nameservers": [+ "google.com",+ "ns1.google.com",+ "ns1.hostingpalvelu.fi",+ "a.dns.gandi.net" ] }Bulk lookups, one request
Look up up to 10 domains in a single HTTP call. One round trip, results returned in input order.
curl -X POST https://rdapapi.io/api/v1/domains/bulk \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"domains": [
"google.com",
"github.com",
"stripe.com"
]
}'{
"results": [
{
"domain": "google.com",
"status": "success",
"registrar": {
"name": "MarkMonitor Inc.",
"iana_id": "292",
"abuse_email": "[email protected]"
},
"dates": { "expires": "2028-09-14T04:00:00Z" },
"nameservers": ["ns1.google.com", "ns2.google.com"]
}
// github.com and stripe.com follow the same shape
],
"summary": { "total": 3, "successful": 3, "failed": 0 }
}Registrar contacts, same request
Some registries (like Verisign for .com and .net) only return basic data. Pass ?follow=true and we fetch the contact details from the registrar for you, merged into a single response.
{ "domain": "google.com", "registrar": { "name": "MarkMonitor Inc.", "iana_id": "292", "abuse_email": "[email protected]" }, "dates": { "registered": "1997-09-15T04:00:00Z", "expires": "2028-09-14T04:00:00Z" }, "nameservers": ["ns1.google.com", "ns2.google.com", "ns3.google.com", "ns4.google.com"],- "entities": {} } { "domain": "google.com", "registrar": { "name": "MarkMonitor Inc.", "iana_id": "292", "abuse_email": "[email protected]" }, "dates": { "registered": "1997-09-15T04:00:00Z", "expires": "2028-09-14T04:00:00Z" }, "nameservers": ["ns1.google.com", "ns2.google.com", "ns3.google.com", "ns4.google.com"],+ "entities": {+ "registrant": {+ "organization": "Google LLC",+ "country_code": "US"+ },+ "administrative": {+ "organization": "Google LLC",+ "country_code": "US"+ },+ "technical": {+ "organization": "Google LLC",+ "country_code": "US"+ }+ } }Drop-in SDK for your stack
Official Python SDK, Node SDK, PHP SDK, Go SDK and Java SDK. Typed responses, idiomatic in each language, published on the standard package registries.
from rdapapi import RdapApi
api = RdapApi("your-api-key")
domain = api.domain("google.com")
print(domain.registrar.name) # "MarkMonitor Inc."
print(domain.dates.expires) # "2028-09-14T04:00:00Z"
print(domain.nameservers[:2]) # ["ns1.google.com", "ns2.google.com"]
import { RdapClient } from "rdapapi"
const client = new RdapClient("your-api-key")
const domain = await client.domain("google.com")
console.log(domain.registrar.name) // "MarkMonitor Inc."
console.log(domain.dates.expires) // "2028-09-14T04:00:00Z"
console.log(domain.nameservers.slice(0, 2)) // ["ns1.google.com", "ns2.google.com"]
use RdapApi\RdapApi;
$api = new RdapApi('your-api-key');
$domain = $api->domain('google.com');
echo $domain->registrar->name; // "MarkMonitor Inc."
echo $domain->dates->expires; // "2028-09-14T04:00:00Z"
print_r($domain->nameservers); // ["ns1.google.com", "ns2.google.com", ...]
import (
"context"
"fmt"
rdapapi "github.com/rdapapi/rdapapi-go"
)
client := rdapapi.NewClient("your-api-key")
domain, _ := client.Domain(context.Background(), "google.com")
fmt.Println(*domain.Registrar.Name) // "MarkMonitor Inc."
fmt.Println(*domain.Dates.Expires) // "2028-09-14T04:00:00Z"
fmt.Println(domain.Nameservers[:2]) // [ns1.google.com ns2.google.com]
import io.rdapapi.client.RdapClient;
try (RdapClient client = new RdapClient("your-api-key")) {
var domain = client.domain("google.com");
System.out.println(domain.getRegistrar().getName()); // "MarkMonitor Inc."
System.out.println(domain.getDates().getExpires()); // "2028-09-14T04:00:00Z"
System.out.println(domain.getNameservers()); // [ns1.google.com, ...]
}
Built for AI agents too
An MCP server exposes the same lookups to AI agents — domains, IPs, ASNs, nameservers and entities. Same API key, same quota, no second integration to maintain.
{
"mcpServers": {
"rdapapi": {
"type": "http",
"url": "https://rdapapi.io/mcp/rdap",
"headers": { "Authorization": "Bearer YOUR_API_KEY" }
}
}
}What people build with it
Four shapes the same endpoint covers, from a continuous pipeline to a single list.
Enrichment pipelines
Registration data for every domain in your dataset, continuously. Pass ?follow=true and .com or .net lookups carry on to the registrar for contact details, merged into one response.
Availability and registration checks
Whether a name is registered, across every TLD that runs RDAP. A truthful 404 when it is not, so you can act on the answer instead of pattern-matching free text.
One-off list enrichment
You have a list and you need it once. Bulk lookups return the same normalized fields as the single endpoint, with no scraping and no rate-limit engineering of your own.
Abuse and investigation
Route complaints to the registrar published contact. abuse_email and abuse_phone are first-class fields on the registrar object, when the registrar publishes them.
Why RDAP, not WHOIS
WHOIS is a 1982 plain-text protocol with no schema. RDAP replaced it with structured JSON, and ICANN is switching port 43 off for new gTLDs.
WHOIS · 1982
- Port 43, plain text
- No schema, free-text per registry
- Encoding guessing
- Sunsetting for new gTLDs
RDAP · 2015
- HTTPS, JSON
- Schema defined (RFCs 7480-7484)
- UTF-8 throughout
- The ICANN-mandated replacement
Read the deep dive on RDAP vs WHOIS for developers, or see the live port 43 sunset tracker.
Comparing vendors? See our breakdown of WhoisXML API alternatives.
Recent posts
Guides, postmortems, and engineering details.
Frequently asked questions
Quick answers to what developers ask before signing up.
Ship RDAP today.
7-day free trial. Plans from $9/mo. Cancel anytime.