Skip to main content

RDAP Core Specifications

The RDAP (Registration Data Access Protocol) is defined by a series of IETF RFCs that replace the legacy WHOIS protocol with a modern, structured, and RESTful alternative.

RFC 7480 - HTTP Usage in RDAP

Link: https://tools.ietf.org/html/rfc7480 Status: Standards Track (March 2015) Purpose: Defines how HTTP is used as the transport protocol for RDAP.
  • Content Type: Responses MUST use application/rdap+json or application/json
  • HTTP Methods: RDAP uses GET for queries (read-only protocol)
  • Status Codes: Standard HTTP status codes (200 OK, 404 Not Found, 400 Bad Request, etc.)
  • HTTPS: RDAP servers SHOULD use HTTPS for security
  • Redirects: Clients MUST follow HTTP redirects (301, 302, 307, 308)
  • User-Agent: Clients SHOULD identify themselves
Implementation in this client:
// src/client.rs
let response = self.http_client
    .get(url.as_str())
    .header("Accept", "application/rdap+json, application/json")
    .send()
    .await?;

RFC 7482 - RDAP Query Format

Link: https://tools.ietf.org/html/rfc7482 Status: Standards Track (March 2015) Purpose: Specifies the query path segments and URL structure for RDAP requests.
Supported query types:
Resource TypePath SegmentExample
Domain/domain/{domain}/domain/example.com
IPv4 Address/ip/{address}/ip/192.0.2.1
IPv6 Address/ip/{address}/ip/2001:db8::1
IPv4 Network/ip/{cidr}/ip/192.0.2.0/24
IPv6 Network/ip/{cidr}/ip/2001:db8::/32
AS Number/autnum/{number}/autnum/15169
Entity/entity/{handle}/entity/ABC123
Nameserver/nameserver/{name}/nameserver/ns1.example.com
Search queries:
  • /domains?name=example* - Domain search
  • /entities?fn=John* - Entity search by name
  • /nameservers?name=ns*.example.com - Nameserver search
Implementation:
// src/request.rs
pub fn build_url(&self, base: &Url) -> Result<Url> {
    let path = match self.query_type {
        QueryType::Domain | QueryType::Tld => format!("domain/{}", self.query),
        QueryType::Ip => format!("ip/{}", self.query),
        QueryType::Autnum => {
            let num = self.query.strip_prefix("AS")
                .or_else(|| self.query.strip_prefix("as"))
                .unwrap_or(&self.query);
            format!("autnum/{}", num)
        },
        // ...
    };
    base.join(&path).map_err(Into::into)
}

RFC 7483 - JSON Responses for RDAP

Link: https://tools.ietf.org/html/rfc7483 Status: Standards Track (March 2015) Purpose: Defines the JSON data structures for RDAP responses.
Core object classes:
  1. Domain Object - Represents a DNS domain name registration
    • objectClassName: “domain”
    • Fields: ldhName, unicodeName, status, nameservers, secureDNS, entities, events
  2. Entity Object - Represents a person, organization, or role
    • objectClassName: “entity”
    • Fields: handle, vcardArray, roles, publicIds, entities
  3. Nameserver Object - DNS nameserver information
    • objectClassName: “nameserver”
    • Fields: ldhName, unicodeName, ipAddresses
  4. Autnum Object - Autonomous System Number
    • objectClassName: “autnum”
    • Fields: startAutnum, endAutnum, name, type, status, country
  5. IP Network Object - IP address range
    • objectClassName: “ip network”
    • Fields: startAddress, endAddress, ipVersion, name, type, country, parentHandle
Common structures:
  • status - Array of status values (active, locked, transfer prohibited, etc.)
  • events - Array of event objects (registration, expiration, last changed)
  • links - Array of related resources and alternate representations
  • notices - Array of informational messages
  • remarks - Array of additional comments
Implementation:
// src/models/domain.rs
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Domain {
    #[serde(rename = "objectClassName")]
    pub object_class_name: Option<String>,
    
    #[serde(rename = "ldhName")]
    pub ldh_name: Option<String>,
    
    pub status: Vec<String>,
    pub nameservers: Vec<Nameserver>,
    
    #[serde(rename = "secureDNS")]
    pub secure_dns: Option<SecureDns>,
    
    pub entities: Vec<Entity>,
    pub events: Vec<Event>,
    pub links: Vec<Link>,
    // ...
}

RFC 7484 - Finding the Authoritative RDAP Service

Link: https://tools.ietf.org/html/rfc7484 Status: Standards Track (March 2015) Purpose: Describes bootstrap mechanisms for discovering authoritative RDAP servers.
IANA Bootstrap Registries:IANA maintains JSON files mapping resource ranges to RDAP servers:
  1. DNS Bootstrap (dns.json)
    • Maps TLDs to RDAP servers
    • Example: .comhttps://rdap.verisign.com/com/v1/
  2. AS Number Bootstrap (asn.json)
    • Maps AS number ranges to RIR RDAP servers
    • Example: AS15169https://rdap.arin.net/registry
  3. IPv4 Bootstrap (ipv4.json)
    • Maps IPv4 CIDR ranges to RIR RDAP servers
    • Example: 8.0.0.0/8https://rdap.arin.net/registry
  4. IPv6 Bootstrap (ipv6.json)
    • Maps IPv6 CIDR ranges to RIR RDAP servers
    • Example: 2001:db8::/32https://rdap.arin.net/registry
Bootstrap file format:
{
  "version": "1.0",
  "publication": "2024-01-15T10:00:00Z",
  "services": [
    [
      ["com", "net"],
      ["https://rdap.verisign.com/com/v1/", "https://rdap.verisign.com/net/v1/"]
    ],
    [
      ["org"],
      ["https://rdap.publicinterestregistry.org/rdap/"]
    ]
  ]
}
Implementation:
// src/bootstrap.rs
pub async fn lookup(&self, request: &RdapRequest) -> Result<Vec<Url>> {
    match request.query_type {
        QueryType::Domain => {
            // Check TLD overrides first
            if let Some(url) = lookup_tld_override(&self.tld_overrides, &request.query) {
                return Ok(vec![url]);
            }
            // Fetch DNS bootstrap
            let registry = self.fetch_registry(&self.config.bootstrap.dns).await?;
            Ok(self.match_domain(&registry, &request.query))
        }
        QueryType::Ip => {
            let bootstrap_url = if request.query.contains(':') {
                &self.config.bootstrap.ipv6
            } else {
                &self.config.bootstrap.ipv4
            };
            let registry = self.fetch_registry(bootstrap_url).await?;
            self.match_ip(&registry, &request.query)
        }
        // ...
    }
}
TLD Override ExtensionThis client extends RFC 7484 by supporting a local tlds.json file for ccTLDs and other TLDs not in IANA bootstrap. This is checked before IANA bootstrap for faster lookups and support for emerging TLDs.

Contact Data Standards

RFC 6350 - vCard Format Specification

Link: https://tools.ietf.org/html/rfc6350 Status: Standards Track (August 2011) Purpose: Defines the vCard format for representing contact information.
RDAP uses vCard 4.0 for entity contact data. Contact information is embedded in JSON as a vcardArray.vCard properties used in RDAP:
  • fn - Formatted name (full name)
  • n - Name components (surname, given name, etc.)
  • org - Organization
  • adr - Address (street, locality, region, postal code, country)
  • tel - Telephone number
  • email - Email address
  • title - Job title
  • role - Role or occupation
  • lang - Language preference
Example vCard in RDAP:
{
  "vcardArray": [
    "vcard",
    [
      ["version", {}, "text", "4.0"],
      ["fn", {}, "text", "John Doe"],
      ["org", {}, "text", "Example Corp"],
      ["email", {}, "text", "[email protected]"],
      ["tel", {"type": "voice"}, "uri", "tel:+1-555-0100"],
      ["adr", {},
        "text",
        ["", "", "123 Main St", "Anytown", "CA", "12345", "US"]
      ]
    ]
  ]
}
Implementation:
// src/models/vcard.rs
pub struct VCard {
    properties: Vec<VCardProperty>,
}

impl VCard {
    pub fn name(&self) -> Option<String> {
        self.get_text("fn")
    }
    
    pub fn email(&self) -> Option<String> {
        self.get_text("email")
    }
    
    pub fn organization(&self) -> Option<String> {
        self.get_text("org")
    }
}

RFC 7095 - jCard: JSON Representation of vCard

Link: https://tools.ietf.org/html/rfc7095 Status: Standards Track (January 2014) Purpose: Defines JSON format for vCard data (jCard), which RDAP uses for contact information.
jCard represents vCard properties as JSON arrays:
[propertyName, parameters, valueType, propertyValue]
Examples:
// Simple text property
["fn", {}, "text", "John Doe"]

// Property with parameters
["tel", {"type": ["work", "voice"]}, "uri", "tel:+1-555-0100"]

// Multi-valued property
["adr", {"type": "work"}, "text",
  ["", "", "123 Main St", "Anytown", "CA", "12345", "US"]]
// [post-office-box, extended-address, street, locality, region, postal-code, country]
Complete jCard object:
[
  "vcard",
  [
    ["version", {}, "text", "4.0"],
    ["fn", {}, "text", "Jane Doe"],
    ["n", {}, "text", ["Doe", "Jane", "", "", ""]],
    ["email", {}, "text", "[email protected]"],
    ["org", {}, "text", "Example Inc."]
  ]
]
The client parses jCard arrays and provides convenient accessor methods for common properties.

DNSSEC in RDAP

Related RFC: RFC 4034 - Resource Records for DNS Security Extensions RDAP domain objects include secureDNS field for DNSSEC information:
{
  "secureDNS": {
    "delegationSigned": true,
    "dsData": [
      {
        "keyTag": 6125,
        "algorithm": 8,
        "digestType": 2,
        "digest": "80F8B78D23107153578BAD3800E9543500474E5C30C29698B40A3DB23ED9DA9F"
      }
    ]
  }
}

Status Values

Related: EPP Status Codes (derived from RFC 5731) Common RDAP status values:
  • active - Object is active
  • inactive - Object is not active
  • locked - Changes prohibited
  • pending create - Create operation pending
  • pending delete - Delete operation pending
  • pending transfer - Transfer operation pending
  • client delete prohibited - Client-set delete protection
  • client transfer prohibited - Client-set transfer protection
  • client update prohibited - Client-set update protection
  • server delete prohibited - Server-set delete protection
  • server transfer prohibited - Server-set transfer protection
  • server update prohibited - Server-set update protection

Compliance Summary

RFC ComplianceThis RDAP client implements:
  • ✅ RFC 7480 - HTTP transport with proper headers and status handling
  • ✅ RFC 7482 - All query path formats (domain, IP, AS, entity, nameserver)
  • ✅ RFC 7483 - Complete JSON response parsing for all object types
  • ✅ RFC 7484 - Bootstrap service discovery with caching
  • ✅ RFC 6350 - vCard 4.0 contact data
  • ✅ RFC 7095 - jCard JSON representation
Extensions:
  • TLD override system for ccTLDs
  • Multi-layer queries (registry + registrar)
  • IPv6 CIDR retry logic
  • Shorthand IP normalization

Additional Resources

Build docs developers (and LLMs) love