Type something to search...
What Is RDAP, and How Is It Replacing WHOIS?

What Is RDAP, and How Is It Replacing WHOIS?

For decades, the answer to "who registered this domain?" came from WHOIS, a plain-text protocol that predates the web. It worked, but every server formatted its output differently, nothing was encrypted, and there was no way to show different data to different users. The Registration Data Access Protocol (RDAP) was designed to fix all of that, and for generic top-level domains it has now officially replaced WHOIS. This article explains what RDAP is, how it differs from WHOIS, how bootstrap discovery finds the right server, how to read an RDAP response, and how to query it with curl, Python, and Node.js. If you need a refresher on the older system first, start with what WHOIS is and how to look up domain ownership.

What Is RDAP?

RDAP is a protocol for looking up registration data for internet resources: domain names, IP address blocks, and autonomous system numbers. It was developed by the IETF and published as a set of standards, and it is built on familiar web technology:

  • Queries are HTTPS GET requests to predictable URLs.
  • Responses are JSON with a standardized structure.
  • Errors use normal HTTP status codes such as 404 and 429.
  • Servers are discovered through bootstrap files published by IANA.

In short, RDAP is WHOIS rebuilt as a RESTful web API. The same registries and registrars that ran WHOIS servers now run RDAP servers, and the data comes from the same registration databases.

The RDAP Standards

RFCCovers
RFC 7480How RDAP uses HTTP, including content types and status codes
RFC 7481Security services: HTTPS, authentication, and access control
RFC 9082The query format, meaning the URL paths for domains, IPs, and more
RFC 9083The JSON response format
RFC 9224Bootstrap: how clients find the authoritative RDAP server
RFC 8056Mapping of EPP status codes to RDAP status values

RFCs 9082, 9083, and 9224 replaced the original 7482, 7483, and 7484 with clarifications, so you will see both sets of numbers in older documentation.

Why WHOIS Needed Replacing

WHOIS (RFC 3912) is a text query sent to port 43, answered by a block of free-form text. That simplicity caused real problems:

Problem with WHOISHow RDAP addresses it
No standard output formatStandardized JSON with defined field names
No encryptionRuns over HTTPS
No way to find the right serverIANA bootstrap files map TLDs and IP ranges to RDAP servers
Poor support for non-ASCII textUTF-8 JSON and support for internationalized domain names
One view of data for everyoneSupports authentication and differentiated access
Errors buried in textHTTP status codes and structured error responses
Hard to link related recordslinks objects point to related records, such as the registrar's copy

The privacy point became urgent after GDPR. Regulators expected personal data to be hidden from the public but available to parties with a legitimate need. WHOIS cannot tell one requester from another; RDAP can, at least in principle, return more fields to authenticated, authorized users.

The Transition Timeline

  • 2015: The core RDAP RFCs are published.
  • 26 August 2019: ICANN requires gTLD registries and registrars to provide RDAP services.
  • 28 January 2025: The WHOIS "sunset" takes effect. gTLD registries and registrars are no longer contractually required to provide port 43 WHOIS, and RDAP becomes the definitive source for gTLD registration data.

Some gTLD operators still run WHOIS servers for compatibility, but you should not rely on them. Country-code TLDs set their own rules: many ccTLD registries offer RDAP, while others still use only WHOIS or a web form. The IANA bootstrap file, covered next, shows which TLDs have registered RDAP servers. The Regional Internet Registries (ARIN, RIPE NCC, APNIC, LACNIC, and AFRINIC) all run RDAP for IP and ASN data.

How RDAP Bootstrap Works

With WHOIS, finding the right server for a TLD meant asking IANA or relying on a hardcoded list in your client. RDAP formalizes this through bootstrap (RFC 9224). IANA publishes JSON files listing which RDAP base URLs serve which resources:

  • https://data.iana.org/rdap/dns.json for domain TLDs
  • https://data.iana.org/rdap/ipv4.json and ipv6.json for IP ranges
  • https://data.iana.org/rdap/asn.json for AS numbers

The domain file looks like this, abridged:

{
  "version": "1.0",
  "publication": "2026-10-20T19:00:01Z",
  "services": [
    [["com", "net"], ["https://rdap.verisign.com/com/v1/"]],
    [["org"], ["https://rdap.publicinterestregistry.org/rdap/"]]
  ]
}

Each entry pairs a list of TLDs with one or more base URLs. A client takes the TLD of the domain being queried, finds the matching entry, and appends domain/ plus the name to the base URL. For example.com, that gives https://rdap.verisign.com/com/v1/domain/example.com.

If you do not want to implement bootstrap yourself, the community-run redirector at rdap.org does it for you: https://rdap.org/domain/example.com returns an HTTP redirect to the correct registry server.

Registry and Registrar Records

For thin registries such as .com, the registry RDAP response contains the domain's registrar, dates, statuses, and name servers, but not the full contact data. It includes a links entry with "rel": "related" that points to the registrar's RDAP server, where the full (and usually redacted) contact record lives. ICANN Lookup and good RDAP clients follow that link automatically. To understand why there are two records, see registry vs. registrar.

Querying RDAP With curl

A simple domain query:

curl -sL https://rdap.org/domain/example.com

The -L flag follows the redirect from rdap.org to the registry. It is good practice to send the RDAP media type in the Accept header:

curl -sL -H "Accept: application/rdap+json" https://rdap.verisign.com/com/v1/domain/example.com

With jq, you can pull out exactly the fields you need:

# Status codes
curl -sL https://rdap.org/domain/example.com | jq -r '.status[]'

# Registration and expiration dates
curl -sL https://rdap.org/domain/example.com \
  | jq -r '.events[] | "\(.eventAction): \(.eventDate)"'

# Name servers
curl -sL https://rdap.org/domain/example.com | jq -r '.nameservers[].ldhName'

# The registrar's own RDAP record, if the registry links to it
curl -sL https://rdap.org/domain/example.com \
  | jq -r '.links[]? | select(.rel == "related") | .href'

RDAP also covers IP addresses and AS numbers. For example, against ARIN:

curl -s https://rdap.arin.net/registry/ip/8.8.8.8 | jq '{name, handle, startAddress, endAddress}'
curl -s https://rdap.arin.net/registry/autnum/15169 | jq '{name, handle}'

If an address belongs to another region, ARIN redirects you to the right RIR, so add -L when in doubt.

Reading an RDAP Domain Response

Here is a trimmed RDAP response for a domain:

{
  "objectClassName": "domain",
  "ldhName": "EXAMPLEBRAND.COM",
  "handle": "1234567890_DOMAIN_COM-VRSN",
  "status": ["client transfer prohibited"],
  "events": [
    { "eventAction": "registration", "eventDate": "2015-06-02T17:40:11Z" },
    { "eventAction": "expiration", "eventDate": "2027-06-02T17:40:11Z" },
    { "eventAction": "last changed", "eventDate": "2026-03-14T09:12:44Z" },
    {
      "eventAction": "last update of RDAP database",
      "eventDate": "2026-10-26T08:00:00Z"
    }
  ],
  "entities": [
    {
      "objectClassName": "entity",
      "handle": "9999",
      "roles": ["registrar"],
      "publicIds": [{ "type": "IANA Registrar ID", "identifier": "9999" }],
      "vcardArray": [
        "vcard",
        [
          ["version", {}, "text", "4.0"],
          ["fn", {}, "text", "Example Registrar, LLC"]
        ]
      ]
    }
  ],
  "nameservers": [
    { "objectClassName": "nameserver", "ldhName": "NS1.EXAMPLEDNS.NET" },
    { "objectClassName": "nameserver", "ldhName": "NS2.EXAMPLEDNS.NET" }
  ],
  "secureDNS": { "delegationSigned": false },
  "links": [
    {
      "rel": "related",
      "type": "application/rdap+json",
      "href": "https://rdap.example-registrar.com/domain/EXAMPLEBRAND.COM"
    }
  ]
}

The key members:

  • ldhName: the domain in "letters, digits, hyphen" form. Internationalized domains also include unicodeName.
  • status: EPP statuses in RDAP form. clientTransferProhibited becomes client transfer prohibited, and ok becomes active, per RFC 8056. See what registrar lock is for what each means.
  • events: dated lifecycle events. registration and expiration are the ones you will use most.
  • entities: people and organizations attached to the domain, each with roles such as registrar, registrant, administrative, technical, billing, or abuse. Contact details are in vcardArray, which uses the jCard format (RFC 7095). The roles are explained in registrant vs. admin vs. technical contact.
  • nameservers: the delegated name servers.
  • secureDNS: DNSSEC delegation information.
  • links: related resources, including the registrar's record.
  • notices and remarks: terms of service, redaction explanations, and links to ICANN's status code documentation.

Redaction in RDAP

Personal data that would be public in old WHOIS records is usually redacted in RDAP too. Servers either omit the fields, fill them with placeholder text, or list them in a redacted member that names which fields were removed and why. A registrant entity might show only an organization, state or province, and country. This is the same privacy behavior covered in what WHOIS privacy protection is, expressed in JSON.

Errors and Rate Limits

RDAP servers use HTTP status codes:

CodeMeaning in RDAP
200Object found
302, 301Redirect, usually from a bootstrap redirector or another RIR
400Malformed query
404Object not found, which for a domain usually means not registered
429Too many requests; slow down

A 404 from the correct registry is a useful (though not conclusive) signal that a domain is unregistered. Reserved and premium names can still return 404 while being unavailable, so confirm with a registrar before celebrating. For the full method, see how to check if a domain name is available.

Querying RDAP in Code

Python With Bootstrap

This standard-library script downloads the IANA bootstrap file once, finds the right server for each domain, and prints key data:

import json
import urllib.error
import urllib.request

BOOTSTRAP_URL = "https://data.iana.org/rdap/dns.json"
HEADERS = {"Accept": "application/rdap+json"}


def fetch_json(url: str) -> dict:
    req = urllib.request.Request(url, headers=HEADERS)
    with urllib.request.urlopen(req, timeout=15) as resp:
        return json.load(resp)


def load_bootstrap() -> dict:
    data = fetch_json(BOOTSTRAP_URL)
    mapping = {}
    for tlds, urls in data["services"]:
        for tld in tlds:
            mapping[tld.lower()] = urls[0]
    return mapping


def rdap_domain(domain: str, bootstrap: dict) -> dict | None:
    tld = domain.rsplit(".", 1)[-1].lower()
    base = bootstrap.get(tld)
    if base is None:
        raise ValueError(f"No RDAP server registered for .{tld}")
    if not base.endswith("/"):
        base += "/"
    try:
        return fetch_json(f"{base}domain/{domain}")
    except urllib.error.HTTPError as exc:
        if exc.code == 404:
            return None
        raise


def summarize(domain: str, data: dict | None) -> None:
    if data is None:
        print(f"{domain}: not found at registry (possibly available)")
        return
    events = {e["eventAction"]: e["eventDate"] for e in data.get("events", [])}
    registrar = next(
        (
            ent.get("vcardArray", [None, []])[1]
            for ent in data.get("entities", [])
            if "registrar" in ent.get("roles", [])
        ),
        [],
    )
    registrar_name = next((f[3] for f in registrar if f[0] == "fn"), "unknown")
    print(f"{domain}")
    print(f"  registrar:  {registrar_name}")
    print(f"  registered: {events.get('registration', 'n/a')}")
    print(f"  expires:    {events.get('expiration', 'n/a')}")
    print(f"  status:     {', '.join(data.get('status', []))}")


if __name__ == "__main__":
    bootstrap = load_bootstrap()
    for name in ["example.com", "example.org", "this-name-is-probably-free-123.com"]:
        summarize(name, rdap_domain(name, bootstrap))

The dict | None type hints require Python 3.10 or newer. In production, cache the bootstrap file for a day rather than downloading it on every run, and add a delay between queries to respect rate limits.

Node.js

Node 18 and later include fetch, which follows redirects by default:

async function rdapDomain(domain) {
  const res = await fetch(`https://rdap.org/domain/${domain}`, {
    headers: { Accept: "application/rdap+json" },
  });
  if (res.status === 404) return null;
  if (!res.ok) throw new Error(`RDAP lookup failed: HTTP ${res.status}`);
  return res.json();
}

const domain = process.argv[2] || "example.com";
const data = await rdapDomain(domain);

if (!data) {
  console.log(`${domain}: not found`);
} else {
  const expiry = data.events?.find((e) => e.eventAction === "expiration");
  console.log({
    domain: data.ldhName,
    status: data.status,
    expires: expiry?.eventDate ?? "n/a",
    nameservers: (data.nameservers || []).map((ns) => ns.ldhName),
  });
}

Save it as rdap.mjs (top-level await needs an ES module) and run node rdap.mjs example.com.

Practical Uses for RDAP

  • Expiry monitoring: check expiration events across your portfolio and alert well ahead of time. This complements setting up domain auto-renewal.
  • Lock monitoring: alert if a domain's statuses no longer include a transfer prohibition.
  • Name server change detection: compare nameservers with a known-good list to catch hijacking early.
  • Abuse reporting: find the registrar's abuse entity for phishing or malware reports.
  • Availability research: a 404 from the authoritative server is a quick first filter.
  • IP and ASN lookups: identify which network owns an address in logs.

Limitations of RDAP

RDAP is a clear improvement, but it is not perfect:

  • Data is still redacted. RDAP supports tiered access, but for most users the public view hides the same personal data that WHOIS did.
  • Coverage is uneven outside gTLDs. Some ccTLDs have no RDAP server in the bootstrap file.
  • Implementations differ in detail. Field usage, redaction markers, and extensions vary between operators, so robust code checks for missing fields.
  • Rate limits apply. Bulk queries can get you temporarily blocked.

RDAP FAQ

No. Both provide registration data, but WHOIS returns unstructured text over port 43, while RDAP returns standardized JSON over HTTPS with defined fields, error codes, and bootstrap discovery. For gTLDs, RDAP is now the authoritative source.

For gTLDs, ICANN stopped requiring registries and registrars to run port 43 WHOIS as of 28 January 2025. Some still run it, but it is no longer guaranteed. Many ccTLDs still operate WHOIS under their own policies.

No. Public RDAP queries require no authentication. Servers may rate limit heavy use, and some offer extra data to authenticated, authorized users such as law enforcement.

Usually not for individuals. Personal data is redacted under privacy law and registrar policy. You may see the organization, state or province, and country, plus a way to contact the registrant through the registrar.

It is a community-run redirector that uses the IANA bootstrap files to send your query to the correct RDAP server. It is convenient for quick lookups, but production systems can read the bootstrap files directly.

The registry has no record of that name, which usually means it is not registered. Reserved, blocked, or premium names may also return 404, so confirm availability with a registrar.

Yes. The Regional Internet Registries run RDAP servers for IP address blocks and autonomous system numbers, and the IANA bootstrap files map address ranges to the right registry.

Conclusion

RDAP takes everything WHOIS did and puts it on a modern footing: HTTPS instead of plain TCP, standardized JSON instead of free-form text, HTTP status codes instead of error messages buried in prose, and IANA bootstrap files instead of guesswork about which server to ask. Since January 2025 it is the definitive source of registration data for gTLDs, and it already covers IP addresses and AS numbers across all five Regional Internet Registries.

For everyday use, ICANN Lookup or curl against rdap.org will answer most questions. For anything automated, such as expiry alerts, lock monitoring, or portfolio reports, query RDAP directly with a short script and parse the JSON rather than scraping WHOIS text. Expect personal data to stay redacted, and handle missing fields gracefully, because implementations vary.

Here are some useful references for going deeper on RDAP:

  1. ICANN: Registration Data Access Protocol (RDAP) — ICANN's overview of RDAP and the WHOIS transition.
  2. RFC 9083: JSON Responses for the Registration Data Access Protocol — defines the response format, including entities, events, and links.
  3. RFC 9082: Registration Data Access Protocol (RDAP) Query Format — defines the URL paths for each query type.
  4. RFC 9224: Finding the Authoritative Registration Data Access Protocol (RDAP) Service — the bootstrap specification.
  5. IANA: Bootstrap Service Registry for Domain Name Space — the live JSON file mapping TLDs to RDAP servers.
Share :

Related Posts

What Is an Addon Domain vs. a Parked Domain in cPanel?

What Is an Addon Domain vs. a Parked Domain in cPanel?

If you use shared hosting, there is a good chance your control panel is cPanel, and an equally good chance you have wondered what to do with a second

Continue Reading
.com vs .net vs .org: Which Domain Extension Should You Pick?

.com vs .net vs .org: Which Domain Extension Should You Pick?

.com, .net, and .org are the three oldest general-purpose domain extensions still open to everyone, and for decades they were essentially the o

Continue Reading
Domain Expiration Process

Domain Expiration Process

Your domain name is the cornerstone of your online presence. It’s the address that connects visitors to your website and your brand’s identity in the

Continue Reading