RDAP APIRDAP APIAPI reference

API reference

Base URL

https://rdapapi.io/api/v1

Authentication

Authorization: Bearer YOUR_API_KEY

Keys live on the dashboard once you are subscribed.

Domain

Look up one domain, or up to 10 in a single call with the bulk endpoint.

Domain Lookup

GET/domain/{domain}

Registration data for a domain, over RDAP or, where a TLD has none, WHOIS.

Parameters

domainstringRequiredpath

The domain name to look up

followbooleanquery default false

Also fetch contacts from the registrar. Needed for .com and .net (thin registries); elsewhere it only fills gaps. Slower when uncached.

whoisbooleanquery default true

Set false to refuse the WHOIS fallback, so a TLD with no RDAP server returns 404 not_supported. See WHOIS fallback.

Status codes

200

Successful lookup

400

Invalid domain name format

404

No data for this domain. Only not_found means it may be free; not_registrable, domain_reserved and not_supported never do. See Errors.

502

The registry failed to answer (lookup_failed), or we did (bad_gateway). See Errors.

503

Upstream RDAP server temporarily rate-limited

Plus the common errors.

Response fields (44)
  • domainstringgoogle.com

    Queried domain name (lowercase)

  • unicode_namestring | null

    Unicode form as the registry sends it; some send the ASCII name

  • handlestring | null2138514_DOMAIN_COM-VRSN

    Registry-assigned handle

  • statusstring[]["client delete prohibited","client transfer prohibited","server delete prohibited"]

    Always lowercase and space-separated — a registry sending clientDeleteProhibited arrives as client delete prohibited. Values we do not recognise pass through unchanged. See Terminology → Status values.

  • nameserversstring[]["ns1.google.com","ns2.google.com","ns3.google.com","ns4.google.com"]

    List of nameserver hostnames

  • dnssecboolean | nullfalse

    Whether the delegation is signed. null where the registry publishes no DNSSEC status, as .tr, .gg and .nc do not.

  • Contact entities keyed by role (registrant, administrative, technical, billing, abuse). Keys depend on what the registry/registrar provides. See Terminology → Entity roles for what each role means.

  • Fields the server declared withheld, at the same path as in the record. See Redaction.

  • Where the answer came from, and how it was served.

Request

curl https://rdapapi.io/api/v1/domain/google.com \
  -H "Authorization: Bearer YOUR_API_KEY"
import { RdapClient } from "rdapapi";

const client = new RdapClient("YOUR_API_KEY");
const result = await client.domain("google.com");
from rdapapi import RdapApi

api = RdapApi("YOUR_API_KEY")
result = api.domain("google.com")

Response

{
    "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": {},
    "meta": {
        "server": "rdap.verisign.com",
        "source": "rdap",
        "rdap_server": "https://rdap.verisign.com/com/v1/",
        "raw_rdap_url": "https://rdap.verisign.com/com/v1/domain/google.com",
        "cached": true,
        "cache_expires": "2026-02-18T15:30:00Z"
    }
}
{
    "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": {
        "registrant": {
            "handle": null,
            "name": "REDACTED REGISTRANT",
            "organization": "REDACTED FOR PRIVACY",
            "email": "redacted for privacy",
            "phone": "REDACTED FOR PRIVACY",
            "address": "REDACTED FOR PRIVACY\nREDACTED FOR PRIVACY\nCA\nREDACTED FOR PRIVACY",
            "contact_url": "https://domains.markmonitor.com/whois/contact/google.com",
            "country_code": "US"
        },
        "technical": {
            "handle": null,
            "name": null,
            "organization": null,
            "email": null,
            "phone": null,
            "address": null,
            "contact_url": "https://domains.markmonitor.com/whois/contact/google.com",
            "country_code": null
        }
    },
    "meta": {
        "server": "rdap.verisign.com",
        "source": "rdap",
        "rdap_server": "https://rdap.verisign.com/com/v1/",
        "raw_rdap_url": "https://rdap.verisign.com/com/v1/domain/google.com",
        "cached": false,
        "cache_expires": "2026-02-18T15:30:00Z",
        "followed": true,
        "registrar_rdap_server": "https://rdap.markmonitor.com/rdap/domain/GOOGLE.COM"
    }
}
{
    "domain": "google.it",
    "unicode_name": null,
    "handle": null,
    "status": [
        "active"
    ],
    "registrar": {
        "name": "MarkMonitor International Limited",
        "iana_id": null,
        "abuse_email": null,
        "abuse_phone": null,
        "url": "https://www.markmonitor.com/"
    },
    "dates": {
        "registered": "1999-12-10T00:00:00Z",
        "expires": "2027-04-21T00:00:00Z",
        "updated": "2026-06-09T23:13:34Z"
    },
    "nameservers": [
        "ns1.google.com",
        "ns2.google.com"
    ],
    "dnssec": false,
    "entities": {
        "registrant": {
            "handle": null,
            "name": null,
            "organization": "Google Ireland Holdings Unlimited Company",
            "email": null,
            "phone": null,
            "address": "70 Sir John Rogerson's Quay, Dublin, 2, Dublin, IE",
            "contact_url": null,
            "country_code": "IE"
        }
    },
    "meta": {
        "server": "whois.nic.it",
        "source": "whois",
        "cached": false,
        "cache_expires": "2026-02-18T15:30:00Z"
    }
}

Bulk Domain Lookup

POST/domains/bulk

Up to 10 domains in one request (Pro and Business). The batch answers 200 even when some domains fail: check each entry's status and error. Each domain is billed like a single lookup. Uncached batches can take 5–15 seconds.

Parameters

domainsstring[]Requiredbody

List of domain names to look up (max 10). Duplicates are collapsed, ignoring case, so you can get back fewer results than you sent.

followbooleanbody default false

Merge in the contacts held by the registrar, for every domain in the request.

whoisbooleanbody default true

Set false to refuse the WHOIS fallback, for every domain in the request.

Status codes

200

Bulk lookup results. Always returns 200 even if individual domains fail. Check each result's status field for per-domain success/failure.

403

No active subscription or plan upgrade required

422

Validation error

Plus the common errors.

Response fields (57)
  • Ordered list of results matching input order (deduplicated)

Request

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",
          "invalid..com"
      ],
      "follow": false,
      "whois": true
  }'
import { RdapClient } from "rdapapi";

const client = new RdapClient("YOUR_API_KEY");
const result = await client.bulkDomains(["google.com", "github.com", "invalid..com"]);
from rdapapi import RdapApi

api = RdapApi("YOUR_API_KEY")
result = api.bulk_domains(["google.com", "github.com", "invalid..com"])

Response

{
    "results": [
        {
            "domain": "google.com",
            "status": "success",
            "data": {
                "domain": "google.com",
                "unicode_name": null,
                "handle": "2138514_DOMAIN_COM-VRSN",
                "status": [
                    "client delete prohibited",
                    "server delete 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"
                ],
                "dnssec": false,
                "entities": {}
            },
            "meta": {
                "server": "rdap.verisign.com",
                "source": "rdap",
                "rdap_server": "https://rdap.verisign.com/com/v1/",
                "raw_rdap_url": "https://rdap.verisign.com/com/v1/domain/google.com",
                "cached": true,
                "cache_expires": "2026-02-18T15:30:00Z"
            }
        },
        {
            "domain": "github.com",
            "status": "success",
            "data": {
                "domain": "github.com",
                "unicode_name": null,
                "handle": "1264983250_DOMAIN_COM-VRSN",
                "status": [
                    "client delete prohibited",
                    "client transfer prohibited"
                ],
                "registrar": {
                    "name": "MarkMonitor Inc.",
                    "iana_id": "292",
                    "abuse_email": "[email protected]",
                    "abuse_phone": "+12086851750",
                    "url": "http://www.markmonitor.com"
                },
                "dates": {
                    "registered": "2007-10-09T18:20:50Z",
                    "expires": "2026-10-09T18:20:50Z",
                    "updated": "2024-09-08T09:09:41Z"
                },
                "nameservers": [
                    "dns1.p08.nsone.net",
                    "dns2.p08.nsone.net"
                ],
                "dnssec": false,
                "entities": {}
            },
            "meta": {
                "server": "rdap.verisign.com",
                "source": "rdap",
                "rdap_server": "https://rdap.verisign.com/com/v1/",
                "raw_rdap_url": "https://rdap.verisign.com/com/v1/domain/github.com",
                "cached": true,
                "cache_expires": "2026-02-18T16:00:00Z"
            }
        },
        {
            "domain": "invalid..com",
            "status": "error",
            "error": "invalid_domain",
            "message": "The provided domain name is not valid."
        }
    ],
    "summary": {
        "total": 3,
        "successful": 2,
        "failed": 1
    }
}

IP

Look up an IP address or CIDR block.

IP Address Lookup

GET/ip/{ip}

The network an IPv4 or IPv6 address belongs to: the most specific allocation, or the exact block for a CIDR.

Parameters

ipstringRequiredpath

IPv4 or IPv6 address, optionally with CIDR prefix (e.g. 8.8.8.8 or 8.8.8.0/24)

Status codes

200

Successful lookup

400

Invalid IP address format

404

No RDAP data found for this IP address.

  • not_found — the range is covered, but the address has no record.
  • not_supported — the address is outside every allocated range.
502

The registry failed to answer (lookup_failed), or we did (bad_gateway). See Errors.

503

Upstream RDAP server temporarily rate-limited

Plus the common errors.

Response fields (47)
  • handlestring | nullNET-8-8-8-0-2

    Registry-assigned handle

  • namestring | nullGOGL

    Network name

  • typestring | nullDIRECT ALLOCATION

    Allocation type

  • start_addressstring | null8.8.8.0

    Start of the IP address range

  • end_addressstring | null8.8.8.255

    End of the IP address range

  • ip_versionstring | nullv4

    IP version (v4 or v6)

  • parent_handlestring | nullNET-8-0-0-0-0

    Parent network handle

  • countrystring | nullUS

    Country code (if provided by registry)

  • statusstring[]["active"]

    Status codes

  • Contact entities keyed by role (registrant, administrative, technical, billing, abuse)

  • cidrstring[]["8.8.8.0/24"]

    CIDR notation for the network

  • geofeedstring | nullhttps://geofeed.ipxo.com/geofeed.txt

    The network's RFC 8805 geofeed URL, as published. null when there is none.

  • Remarks from the registry (network description, abuse info, etc.)

  • port43string | nullwhois.apnic.net

    Legacy WHOIS server hostname

  • Fields the server declared withheld, at the same path as in the record. See Redaction.

  • Where the answer came from, and how it was served.

Request

curl https://rdapapi.io/api/v1/ip/8.8.8.8 \
  -H "Authorization: Bearer YOUR_API_KEY"
import { RdapClient } from "rdapapi";

const client = new RdapClient("YOUR_API_KEY");
const result = await client.ip("8.8.8.8");
from rdapapi import RdapApi

api = RdapApi("YOUR_API_KEY")
result = api.ip("8.8.8.8")

Response

{
    "handle": "NET-8-8-8-0-2",
    "name": "GOGL",
    "type": "DIRECT ALLOCATION",
    "start_address": "8.8.8.0",
    "end_address": "8.8.8.255",
    "ip_version": "v4",
    "parent_handle": "NET-8-0-0-0-0",
    "country": null,
    "status": [
        "active"
    ],
    "dates": {
        "registered": "2023-12-28T22:24:33Z",
        "expires": null,
        "updated": "2023-12-28T22:24:56Z"
    },
    "entities": {
        "registrant": {
            "handle": "GOGL",
            "name": "Google LLC",
            "organization": null,
            "email": null,
            "phone": null,
            "address": "1600 Amphitheatre Parkway\nMountain View\nCA\n94043\nUnited States",
            "contact_url": null,
            "country_code": null
        }
    },
    "cidr": [
        "8.8.8.0/24"
    ],
    "geofeed": null,
    "remarks": [],
    "port43": "whois.arin.net",
    "meta": {
        "server": "rdap.arin.net",
        "source": "rdap",
        "rdap_server": "https://rdap.arin.net/registry/",
        "raw_rdap_url": "https://rdap.arin.net/registry/ip/8.8.8.8",
        "cached": false,
        "cache_expires": "2026-02-24T15:30:00Z"
    }
}

ASN

Look up an Autonomous System Number.

ASN Lookup

GET/asn/{asn}

Query RDAP registration data for an ASN.

Parameters

asnstringRequiredpath

Autonomous System Number (1–4,294,967,295), optionally prefixed with "AS"

Status codes

200

Successful lookup

400

Invalid ASN format

404

No RDAP data found for this ASN.

  • not_found — the range is covered, but the number has no record.
  • not_supported — the number is outside every allocated range.
502

The registry failed to answer (lookup_failed), or we did (bad_gateway). See Errors.

503

Upstream RDAP server temporarily rate-limited

Plus the common errors.

Response fields (43)
  • handlestring | nullAS15169

    Registry-assigned handle

  • namestring | nullGOOGLE

    Autonomous system name

  • typestring | null

    Allocation type

  • start_autnuminteger | null15169

    Start of the ASN range

  • end_autnuminteger | null15169

    End of the ASN range

  • countrystring | null

    ISO 3166-1 alpha-2 country code, from the record or else a contact's address. APNIC and Brazil's registro.br usually publish one; ARIN, RIPE NCC, AFRINIC and LACNIC usually don't.

  • statusstring[]["active"]

    Status codes

  • Contact entities keyed by role (registrant, administrative, technical, billing, abuse)

  • Remarks from the registry (AS description, abuse info, etc.)

  • port43string | nullwhois.arin.net

    Legacy WHOIS server hostname

  • Fields the server declared withheld, at the same path as in the record. See Redaction.

  • Where the answer came from, and how it was served.

Request

curl https://rdapapi.io/api/v1/asn/15169 \
  -H "Authorization: Bearer YOUR_API_KEY"
import { RdapClient } from "rdapapi";

const client = new RdapClient("YOUR_API_KEY");
const result = await client.asn("15169");
from rdapapi import RdapApi

api = RdapApi("YOUR_API_KEY")
result = api.asn("15169")

Response

{
    "handle": "AS15169",
    "name": "GOOGLE",
    "type": null,
    "start_autnum": 15169,
    "end_autnum": 15169,
    "country": null,
    "status": [
        "active"
    ],
    "dates": {
        "registered": "2000-03-30T05:00:00Z",
        "expires": null,
        "updated": "2012-02-24T14:44:34Z"
    },
    "entities": {
        "registrant": {
            "handle": "GOGL",
            "name": "Google LLC",
            "organization": null,
            "email": null,
            "phone": null,
            "address": "1600 Amphitheatre Parkway\nMountain View\nCA\n94043\nUnited States",
            "contact_url": null,
            "country_code": null
        },
        "technical": {
            "handle": "ZG39-ARIN",
            "name": "Google LLC",
            "organization": "Google LLC",
            "email": "[email protected]",
            "phone": "+16502530000",
            "address": "1600 Amphitheatre Parkway\nMountain View\nCA\n94043\nUnited States",
            "contact_url": null,
            "country_code": null
        }
    },
    "remarks": [],
    "port43": "whois.arin.net",
    "meta": {
        "server": "rdap.arin.net",
        "source": "rdap",
        "rdap_server": "https://rdap.arin.net/registry/",
        "raw_rdap_url": "https://rdap.arin.net/registry/autnum/15169",
        "cached": false,
        "cache_expires": "2026-02-24T15:30:00Z"
    }
}

Nameserver

Look up a nameserver host record, for the registries that publish one.

Nameserver Lookup

GET/nameserver/{host}

Registration data for a nameserver hostname, from the registries that publish one.

Parameters

hoststringRequiredpath

Nameserver hostname to look up

Status codes

200

Successful lookup

400

Invalid nameserver hostname format

404

No RDAP data found for this nameserver.

  • not_found — the TLD is covered, but no record exists for this host.
  • not_supported — the nameserver's TLD has no RDAP coverage.
502

The registry failed to answer (lookup_failed), or we did (bad_gateway). See Errors.

503

Upstream RDAP server temporarily rate-limited

Plus the common errors.

Response fields (39)
  • ldh_namestringns1.google.com

    Nameserver hostname (lowercase). Empty string if the upstream returned a value that is not a valid LDH hostname.

  • unicode_namestring | null

    Unicode form as the registry sends it; some send the ASCII name

  • handlestring | nullNS1.GOOGLE.COM

    Registry-assigned handle

  • statusstring[]["active"]

    Status codes

  • Contact entities keyed by role (registrant, administrative, technical, billing, abuse)

  • Fields the server declared withheld, at the same path as in the record. See Redaction.

  • Where the answer came from, and how it was served.

Request

curl https://rdapapi.io/api/v1/nameserver/ns1.google.com \
  -H "Authorization: Bearer YOUR_API_KEY"
import { RdapClient } from "rdapapi";

const client = new RdapClient("YOUR_API_KEY");
const result = await client.nameserver("ns1.google.com");
from rdapapi import RdapApi

api = RdapApi("YOUR_API_KEY")
result = api.nameserver("ns1.google.com")

Response

{
    "ldh_name": "ns1.google.com",
    "unicode_name": null,
    "handle": "NS1.GOOGLE.COM",
    "ip_addresses": {
        "v4": [
            "216.239.32.10"
        ],
        "v6": [
            "2001:4860:4802:32::a"
        ]
    },
    "status": [
        "active"
    ],
    "dates": {
        "registered": "2004-01-01T00:00:00Z",
        "expires": null,
        "updated": "2024-06-15T12:00:00Z"
    },
    "entities": {},
    "meta": {
        "server": "rdap.verisign.com",
        "source": "rdap",
        "rdap_server": "https://rdap.verisign.com/com/v1/",
        "raw_rdap_url": "https://rdap.verisign.com/com/v1/nameserver/ns1.google.com",
        "cached": false,
        "cache_expires": "2026-02-24T15:30:00Z"
    }
}

Entity

Look up a contact or organization by RDAP handle.

Entity Lookup

GET/entity/{handle}

An organization or contact at ARIN, RIPE NCC, APNIC, LACNIC or AFRINIC, by handle. The suffix picks the registry (-RIPE, -AP…); a bare handle like GOGL goes to ARIN.

Parameters

handlestringRequiredpath

Entity handle (e.g. GOGL, ABUSE5250-ARIN, ORG-GLLC1-RIPE)

Status codes

200

Successful lookup

400

Invalid entity handle format

404

No RDAP data found for this entity handle.

  • not_found — the handle belongs to a regional registry, but no matching entity exists.
  • not_supported — the handle does not look like one from a supported registry.
502

The registry failed to answer (lookup_failed), or we did (bad_gateway). See Errors.

503

Upstream RDAP server temporarily rate-limited

Plus the common errors.

Response fields (61)
  • handlestring | nullGOGL

    Registry-assigned entity handle

  • namestring | nullGoogle LLC

    Full name (fn from vCard)

  • organizationstring | nullGoogle LLC

    Organization name

  • emailstring | null

    Contact email address

  • phonestring | null

    Voice telephone number in E.164, with a ;ext=42 suffix when the registry supplies an extension.

  • addressstring | null

    Postal address

  • contact_urlstring | null

    Web form or page for reaching this contact, where one is published instead of an email address.

  • country_codestring | nullUS

    ISO 3166-1 alpha-2 country code

  • rolesstring[]["registrant"]

    Roles this entity serves

  • statusstring[]["active"]

    Status codes

  • port43string | nullwhois.arin.net

    Legacy WHOIS server hostname

  • Public identifiers (e.g. ARIN OrgID, IANA Registrar ID)

  • Nested contact entities keyed by role

  • Autonomous system numbers owned by this entity

  • IP network blocks owned by this entity

  • Fields the server declared withheld, at the same path as in the record. See Redaction.

  • Where the answer came from, and how it was served.

Request

curl https://rdapapi.io/api/v1/entity/GOGL \
  -H "Authorization: Bearer YOUR_API_KEY"
import { RdapClient } from "rdapapi";

const client = new RdapClient("YOUR_API_KEY");
const result = await client.entity("GOGL");
from rdapapi import RdapApi

api = RdapApi("YOUR_API_KEY")
result = api.entity("GOGL")

Response

{
    "handle": "GOGL",
    "name": "Google LLC",
    "organization": "Google LLC",
    "email": null,
    "phone": null,
    "address": "1600 Amphitheatre Parkway\nMountain View\nCA\n94043\nUS",
    "contact_url": null,
    "country_code": "US",
    "roles": [
        "registrant"
    ],
    "status": [
        "active"
    ],
    "dates": {
        "registered": "2000-03-30T05:00:00Z",
        "expires": null,
        "updated": "2019-10-31T19:45:45Z"
    },
    "remarks": [
        {
            "title": "Registration Comments",
            "description": "Please note that the recommended way to file abuse complaints are located in the following links."
        }
    ],
    "port43": "whois.arin.net",
    "public_ids": [
        {
            "type": "ARIN OrgID",
            "identifier": "GOGL"
        }
    ],
    "entities": {
        "abuse": {
            "handle": "ABUSE5250-ARIN",
            "name": "Abuse",
            "organization": null,
            "email": "[email protected]",
            "phone": "+16502530000",
            "address": null,
            "contact_url": null,
            "country_code": null
        }
    },
    "autnums": [
        {
            "handle": "AS15169",
            "name": "GOOGLE",
            "start_autnum": 15169,
            "end_autnum": 15169
        },
        {
            "handle": "AS36040",
            "name": "YOUTUBE",
            "start_autnum": 36040,
            "end_autnum": 36040
        }
    ],
    "networks": [
        {
            "handle": "NET-8-8-8-0-2",
            "name": "GOGL",
            "start_address": "8.8.8.0",
            "end_address": "8.8.8.255",
            "ip_version": "v4",
            "cidr": [
                "8.8.8.0/24"
            ]
        }
    ],
    "meta": {
        "server": "rdap.arin.net",
        "source": "rdap",
        "rdap_server": "https://rdap.arin.net/registry/",
        "raw_rdap_url": "https://rdap.arin.net/registry/entity/GOGL",
        "cached": false,
        "cache_expires": "2026-02-24T15:30:00Z"
    }
}

TLDs

Check which TLDs are supported, in bulk or one at a time.

List Supported TLDs

GET/tlds

Every TLD we answer for: its protocol, when support was added, and how often its registry fills the main fields (field availability). Free, sorted by tld, and sent with an ETag: pass it as If-None-Match to get 304 Not Modified.

Parameters

sincestringquery

ISO 8601 timestamp. Only TLDs supported after it.

serverstringquery

Only TLDs answered by this server, e.g. rdap.verisign.com.

Status codes

200

List of supported TLDs

304

Not modified. Returned when the If-None-Match header matches the current ETag. No response body.

400

Invalid since query parameter

Plus the common errors.

Response fields (21)

Request

curl https://rdapapi.io/api/v1/tlds \
  -H "Authorization: Bearer YOUR_API_KEY"
import { RdapClient } from "rdapapi";

const client = new RdapClient("YOUR_API_KEY");
const result = await client.tlds();
from rdapapi import RdapApi

api = RdapApi("YOUR_API_KEY")
result = api.tlds()

Response

{
    "data": [
        {
            "tld": "com",
            "supported_since": "2026-03-07T00:00:00Z",
            "rdap_server_host": "rdap.verisign.com",
            "rdap_server_url": "https://rdap.verisign.com/com/v1/",
            "field_availability": {
                "registrar": "sometimes",
                "registered_at": "always",
                "expires_at": "always",
                "nameservers": "always",
                "status": "always"
            }
        },
        {
            "tld": "fr",
            "supported_since": "2026-03-07T00:00:00Z",
            "rdap_server_host": "rdap.nic.fr",
            "rdap_server_url": "https://rdap.nic.fr/",
            "field_availability": null
        }
    ],
    "meta": {
        "computed_at": "2026-04-22T10:00:00Z",
        "count": 2,
        "coverage": 0.5,
        "thresholds": {
            "always": 0.99,
            "usually": 0.8,
            "sometimes": 0
        }
    }
}

Get a Single TLD

GET/tlds/{tld}

The same object as in the list, for one TLD. Free.

Parameters

tldstringRequiredpath

Lowercase TLD label without a leading dot (e.g. com, fr, co.uk).

Status codes

200

TLD found

304

Not modified.

404

Unknown TLD

Plus the common errors.

Response fields (19)

Request

curl https://rdapapi.io/api/v1/tlds/com \
  -H "Authorization: Bearer YOUR_API_KEY"
import { RdapClient } from "rdapapi";

const client = new RdapClient("YOUR_API_KEY");
const result = await client.tld("com");
from rdapapi import RdapApi

api = RdapApi("YOUR_API_KEY")
result = api.tld("com")

Response

{
    "data": {
        "tld": "com",
        "supported_since": "2026-03-07T00:00:00Z",
        "rdap_server_host": "rdap.verisign.com",
        "rdap_server_url": "https://rdap.verisign.com/com/v1/",
        "field_availability": {
            "registrar": "sometimes",
            "registered_at": "always",
            "expires_at": "always",
            "nameservers": "always",
            "status": "always"
        }
    },
    "meta": {
        "computed_at": "2026-04-22T10:00:00Z",
        "thresholds": {
            "always": 0.99,
            "usually": 0.8,
            "sometimes": 0
        }
    }
}

Health

Uptime checks.

Health Check

GET/ping

Returns {"status":"ok"} when the API is up. No key, free.

Status codes

200

API is reachable

Plus the common errors.

Response fields (1)
  • statusstringok

Request

curl https://rdapapi.io/api/v1/ping

Response

{
    "status": "ok"
}

Errors

Errors are JSON with an error code to branch on and a message to show. Some add retry_after, in seconds.

Status error Meaning Retry?
400 invalid_domain, invalid_ip, invalid_asn, invalid_nameserver, invalid_handle, invalid_prefix, invalid_since The identifier is malformed. No
4xx bad_request, method_not_allowed, payload_too_large Malformed request, wrong method or body too large. No
401 unauthenticated Missing or invalid API key. No
403 subscription_required No active subscription. No
403 plan_upgrade_required Bulk needs Pro or Business. No
403 forbidden Your IP is temporarily blocked. Later
404 not_found No record. For a domain, the name may be free. No
404 domain_reserved Reserved by the registry; reason says why. No
404 not_registrable Below a registration, like www.example.com; look up registrable_domain. No
404 not_supported We can't query this TLD, zone or range. No
404 unknown_endpoint No such endpoint. No
422 request_failed Invalid body; errors lists the fields. No
429 rate_limit_exceeded Per-minute limit reached. After retry_after
429 quota_exceeded Monthly quota spent. Next month
429 too_many_requests Too many requests at once. Shortly
502 lookup_failed The registry failed to answer. Yes
503 temporarily_unavailable The registry is throttling us. After retry_after
5xx bad_gateway, service_unavailable, gateway_timeout, server_error A problem on our side. Shortly

Lookup 404s are billed like successes (Limits and caching). Send Accept: application/json so an error from our CDN stays JSON; treat any non-JSON error as a retryable network failure.

Limits and caching

Rate limit. X-RateLimit-Limit and X-RateLimit-Remaining track your per-minute limit. Over it you get 429 rate_limit_exceeded with Retry-After. A bulk request spends one unit per domain; very large bursts are also cut at the edge (429 too_many_requests).

Quota. Successful lookups and lookup 404s count, cached or not; nothing else does, and /tlds and /ping are free. ?follow=true counts once; a bulk request counts each domain. Over quota you get 429 quota_exceeded until the 1st of next month (UTC).

Caching. Lookups are cached for up to 24 hours (meta.cached, meta.cache_expires), may be served up to 24 hours past expiry while refreshing, and up to 7 days old if the registry doesn't answer. /tlds supports ETag revalidation.

WHOIS fallback

TLDs with no RDAP server, mostly ccTLDs such as .it, .eu and .tr, are read from the registry's WHOIS server and returned in the same shape with meta.source: whois. /tlds lists them as protocol: whois. Errors, snapshots and billing work the same. Send whois=false to refuse it (404 not_supported). Domains only: the five RIRs all run RDAP.

Terminology

Thin and thick registries

A thin registry (.com, .net, .cc, .tv) leaves contacts to the registrar. A thick registry, like most ccTLDs and newer gTLDs, publishes the full record itself.

Follow-through

?follow=true also queries the registrar named in the registry's answer and merges in its contacts. If that fails you still get the registry data, with meta.followed: false and a meta.follow_error; false with no error means there was nothing to follow.

Entity roles

entities is keyed by role: registrant (the holder), administrative, technical, billing and abuse, one contact each. The registrar is the top-level registrar field. Which roles appear depends on what the registry publishes; placeholders such as Redacted for Privacy are passed through as sent.

Field availability

/tlds rates how often a TLD fills each field over 90 days: always (≥99%), usually (≥80%), sometimes or never, and null until there is enough data.

Status values

status uses the lowercase RDAP names (client transfer prohibited); EPP forms like clientTransferProhibited are converted. Registry-specific values pass through, so don't match against a closed list. Every status, explained.

Redaction

Since GDPR most contact fields are null. When a registry says why, redacted mirrors the record (redacted.entities.registrant.name) with the method: removal or emptyValue (blanked), partialValue (incomplete), or replacementValue, a genuine-looking substitute such as a forwarding address. No redacted doesn't mean nothing was withheld.