openapi: 3.1.0
info:
  title: RDAP API
  description: |
    Query registration data using the **RDAP protocol** — the official replacement for WHOIS.

    Look up domains, IP addresses, ASNs, nameservers, and entities via a simple REST API. Clean JSON responses, consistent format across all supported registries.

    ## Authentication

    All API requests require a Bearer token. Include it in the `Authorization` header:

    ```
    Authorization: Bearer YOUR_API_KEY
    ```

    Don't have an API key? [Create a free account](https://rdapapi.io/register) to get one.

    ## Caching

    Responses are cached for **24 hours** to avoid hitting upstream registry rate limits.
    Cached responses are significantly faster (sub-50ms vs 200–2000ms for fresh queries).
    The `meta` object in every response contains cache state and RDAP server info.

    ## Client Libraries

    - **Python**: [`pip install rdapapi`](https://pypi.org/project/rdapapi/) — [GitHub](https://github.com/rdapapi/python-sdk)
  version: 1.0.0
  contact:
    name: RDAP API Support
    url: https://rdapapi.io

servers:
  - url: https://rdapapi.io/api/v1
    description: Production
  - url: http://localhost/api/v1
    description: Local development

security:
  - bearerAuth: []

components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: API key obtained from your dashboard

  schemas:
    Registrar:
      type: object
      properties:
        name:
          type: string
          nullable: true
          example: MarkMonitor Inc.
        iana_id:
          type: string
          nullable: true
          example: "292"
        abuse_email:
          type: string
          nullable: true
          example: abusecomplaints@markmonitor.com
        abuse_phone:
          type: string
          nullable: true
          example: "+1.2086851750"
        url:
          type: string
          nullable: true
          example: http://www.markmonitor.com

    Dates:
      type: object
      properties:
        registered:
          type: string
          format: date-time
          nullable: true
          example: "1997-09-15T04:00:00Z"
        expires:
          type: string
          format: date-time
          nullable: true
          example: "2028-09-14T04:00:00Z"
        updated:
          type: string
          format: date-time
          nullable: true
          example: "2019-09-09T15:39:04Z"

    Remark:
      type: object
      properties:
        title:
          type: string
          nullable: true
          example: description
        description:
          type: string
          example: "APNIC and Cloudflare DNS Resolver project\nRouted globally by AS13335/Cloudflare"

    Contact:
      type: object
      properties:
        handle:
          type: string
          nullable: true
          description: Registry handle for this entity
          example: ORG-ARAD1-AP
        name:
          type: string
          nullable: true
        organization:
          type: string
          nullable: true
          example: Google LLC
        email:
          type: string
          nullable: true
        phone:
          type: string
          nullable: true
        address:
          type: string
          nullable: true
        contact_url:
          type: string
          nullable: true
          description: Privacy proxy contact URL (RFC 8605 contact-uri)
          example: "https://domaincontact.registrar.cloudflare.com/example.com"
        country_code:
          type: string
          nullable: true
          description: ISO 3166-1 alpha-2 country code from the address
          example: US

    DomainResponse:
      type: object
      properties:
        domain:
          type: string
          description: Queried domain name (lowercase)
          example: google.com
        unicode_name:
          type: string
          nullable: true
          description: Unicode representation for IDN domains
        handle:
          type: string
          nullable: true
          description: Registry-assigned handle
          example: 2138514_DOMAIN_COM-VRSN
        status:
          type: array
          items:
            type: string
          description: EPP status codes (RFC 9083 lowercase, space-separated)
          example:
            - client delete prohibited
            - client transfer prohibited
            - server delete prohibited
        registrar:
          $ref: '#/components/schemas/Registrar'
        dates:
          $ref: '#/components/schemas/Dates'
        nameservers:
          type: array
          items:
            type: string
          description: List of nameserver hostnames
          example:
            - ns1.google.com
            - ns2.google.com
            - ns3.google.com
            - ns4.google.com
        dnssec:
          type: boolean
          description: Whether DNSSEC delegation is signed
          example: false
        entities:
          type: object
          description: Contact entities keyed by role (registrant, administrative, technical, billing). Keys depend on what the registry/registrar provides.
          properties:
            registrant:
              $ref: '#/components/schemas/Contact'
            administrative:
              $ref: '#/components/schemas/Contact'
            technical:
              $ref: '#/components/schemas/Contact'
            billing:
              $ref: '#/components/schemas/Contact'
        meta:
          $ref: '#/components/schemas/Meta'

    Meta:
      type: object
      properties:
        rdap_server:
          type: string
          description: Authoritative RDAP server URL
          example: https://rdap.verisign.com/com/v1/
        raw_rdap_url:
          type: string
          description: Direct URL to the raw RDAP response
          example: https://rdap.verisign.com/com/v1/domain/google.com
        cached:
          type: boolean
          description: Whether the response was served from cache
          example: true
        cache_expires:
          type: string
          format: date-time
          description: Cache expiration time (ISO 8601)
          example: "2026-02-18T15:30:00Z"
        followed:
          type: boolean
          description: Whether the registrar's RDAP server was queried for richer data. Only present when `?follow=true` is used.
        registrar_rdap_server:
          type: string
          nullable: true
          description: URL of the registrar's RDAP server that was followed. Only present when `?follow=true` is used.
        follow_error:
          type: string
          nullable: true
          description: Error message if the follow request failed. Only present when `?follow=true` is used and the request fails.

    IpResponse:
      type: object
      properties:
        handle:
          type: string
          nullable: true
          description: Registry-assigned handle
          example: NET-8-8-8-0-2
        name:
          type: string
          nullable: true
          description: Network name
          example: GOGL
        type:
          type: string
          nullable: true
          description: Allocation type
          example: DIRECT ALLOCATION
        start_address:
          type: string
          nullable: true
          description: Start of the IP address range
          example: "8.8.8.0"
        end_address:
          type: string
          nullable: true
          description: End of the IP address range
          example: "8.8.8.255"
        ip_version:
          type: string
          nullable: true
          description: IP version (v4 or v6)
          example: v4
        parent_handle:
          type: string
          nullable: true
          description: Parent network handle
          example: NET-8-0-0-0-0
        country:
          type: string
          nullable: true
          description: Country code (if provided by registry)
          example: US
        status:
          type: array
          items:
            type: string
          description: Status codes
          example:
            - active
        dates:
          $ref: '#/components/schemas/Dates'
        entities:
          type: object
          description: Contact entities keyed by role (registrant, administrative, technical, abuse)
          properties:
            registrant:
              $ref: '#/components/schemas/Contact'
            administrative:
              $ref: '#/components/schemas/Contact'
            technical:
              $ref: '#/components/schemas/Contact'
            abuse:
              $ref: '#/components/schemas/Contact'
        cidr:
          type: array
          items:
            type: string
          description: CIDR notation for the network
          example:
            - "8.8.8.0/24"
        remarks:
          type: array
          items:
            $ref: '#/components/schemas/Remark'
          description: Remarks from the registry (network description, abuse info, etc.)
        port43:
          type: string
          nullable: true
          description: Legacy WHOIS server hostname
          example: whois.apnic.net
        meta:
          $ref: '#/components/schemas/Meta'

    AsnResponse:
      type: object
      properties:
        handle:
          type: string
          nullable: true
          description: Registry-assigned handle
          example: AS15169
        name:
          type: string
          nullable: true
          description: Autonomous system name
          example: GOOGLE
        type:
          type: string
          nullable: true
          description: Allocation type
        start_autnum:
          type: integer
          nullable: true
          description: Start of the ASN range
          example: 15169
        end_autnum:
          type: integer
          nullable: true
          description: End of the ASN range
          example: 15169
        status:
          type: array
          items:
            type: string
          description: Status codes
          example:
            - active
        dates:
          $ref: '#/components/schemas/Dates'
        entities:
          type: object
          description: Contact entities keyed by role (registrant, administrative, technical, abuse)
          properties:
            registrant:
              $ref: '#/components/schemas/Contact'
            administrative:
              $ref: '#/components/schemas/Contact'
            technical:
              $ref: '#/components/schemas/Contact'
            abuse:
              $ref: '#/components/schemas/Contact'
        remarks:
          type: array
          items:
            $ref: '#/components/schemas/Remark'
          description: Remarks from the registry (AS description, abuse info, etc.)
        port43:
          type: string
          nullable: true
          description: Legacy WHOIS server hostname
          example: whois.arin.net
        meta:
          $ref: '#/components/schemas/Meta'

    NameserverResponse:
      type: object
      properties:
        ldh_name:
          type: string
          description: Nameserver hostname (lowercase)
          example: ns1.google.com
        unicode_name:
          type: string
          nullable: true
          description: Unicode representation for IDN nameserver hostnames
        handle:
          type: string
          nullable: true
          description: Registry-assigned handle
          example: NS1.GOOGLE.COM
        ip_addresses:
          type: object
          properties:
            v4:
              type: array
              items:
                type: string
              description: IPv4 addresses
              example:
                - "216.239.32.10"
            v6:
              type: array
              items:
                type: string
              description: IPv6 addresses
              example:
                - "2001:4860:4802:32::a"
        status:
          type: array
          items:
            type: string
          description: Status codes
          example:
            - active
        dates:
          $ref: '#/components/schemas/Dates'
        entities:
          type: object
          description: Contact entities keyed by role
          properties:
            registrant:
              $ref: '#/components/schemas/Contact'
            administrative:
              $ref: '#/components/schemas/Contact'
            technical:
              $ref: '#/components/schemas/Contact'
        meta:
          $ref: '#/components/schemas/Meta'

    PublicId:
      type: object
      properties:
        type:
          type: string
          nullable: true
          description: Type of public identifier
          example: ARIN OrgID
        identifier:
          type: string
          nullable: true
          description: The identifier value
          example: GOGL

    EntityResponse:
      type: object
      properties:
        handle:
          type: string
          nullable: true
          description: Registry-assigned entity handle
          example: GOGL
        name:
          type: string
          nullable: true
          description: Full name (fn from vCard)
          example: Google LLC
        organization:
          type: string
          nullable: true
          description: Organization name
          example: Google LLC
        email:
          type: string
          nullable: true
          description: Contact email address
        phone:
          type: string
          nullable: true
          description: Voice telephone number
        address:
          type: string
          nullable: true
          description: Postal address
        contact_url:
          type: string
          nullable: true
          description: Contact URI (RFC 8605)
        country_code:
          type: string
          nullable: true
          description: ISO 3166-1 alpha-2 country code
          example: US
        roles:
          type: array
          items:
            type: string
          description: Roles this entity serves
          example:
            - registrant
        status:
          type: array
          items:
            type: string
          description: Status codes
          example:
            - active
        dates:
          $ref: '#/components/schemas/Dates'
        remarks:
          type: array
          items:
            $ref: '#/components/schemas/Remark'
        port43:
          type: string
          nullable: true
          description: Legacy WHOIS server hostname
          example: whois.arin.net
        public_ids:
          type: array
          items:
            $ref: '#/components/schemas/PublicId'
          description: Public identifiers (e.g. ARIN OrgID, IANA Registrar ID)
        entities:
          type: object
          description: Nested contact entities keyed by role
          properties:
            registrant:
              $ref: '#/components/schemas/Contact'
            abuse:
              $ref: '#/components/schemas/Contact'
            administrative:
              $ref: '#/components/schemas/Contact'
            technical:
              $ref: '#/components/schemas/Contact'
            billing:
              $ref: '#/components/schemas/Contact'
        autnums:
          type: array
          description: Autonomous system numbers owned by this entity
          items:
            $ref: '#/components/schemas/EntityAutnum'
        networks:
          type: array
          description: IP network blocks owned by this entity
          items:
            $ref: '#/components/schemas/EntityNetwork'
        meta:
          $ref: '#/components/schemas/Meta'

    EntityAutnum:
      type: object
      properties:
        handle:
          type: string
          nullable: true
          example: AS15169
        name:
          type: string
          nullable: true
          example: GOOGLE
        start_autnum:
          type: integer
          nullable: true
          example: 15169
        end_autnum:
          type: integer
          nullable: true
          example: 15169

    EntityNetwork:
      type: object
      properties:
        handle:
          type: string
          nullable: true
          example: NET-8-8-8-0-2
        name:
          type: string
          nullable: true
          example: GOGL
        start_address:
          type: string
          nullable: true
          example: 8.8.8.0
        end_address:
          type: string
          nullable: true
          example: 8.8.8.255
        ip_version:
          type: string
          nullable: true
          example: v4
        cidr:
          type: array
          items:
            type: string
          example:
            - 8.8.8.0/24

    BulkDomainResult:
      type: object
      description: Result for a single domain in a bulk lookup
      properties:
        domain:
          type: string
          description: The queried domain name
          example: google.com
        status:
          type: string
          enum: [success, error]
          description: Whether this individual lookup succeeded
          example: success
        data:
          $ref: '#/components/schemas/DomainResponse'
          description: Domain lookup data (present when status is "success")
        meta:
          $ref: '#/components/schemas/Meta'
          description: Cache and RDAP server info (present when status is "success")
        error:
          type: string
          description: Machine-readable error code (present when status is "error")
          example: not_found
        message:
          type: string
          description: Human-readable error message (present when status is "error")
          example: "No RDAP data found for domain: nonexistent.example"

    BulkDomainSummary:
      type: object
      properties:
        total:
          type: integer
          description: Total number of unique domains processed
          example: 3
        successful:
          type: integer
          description: Number of successful lookups
          example: 2
        failed:
          type: integer
          description: Number of failed lookups
          example: 1

    BulkDomainResponse:
      type: object
      properties:
        results:
          type: array
          items:
            $ref: '#/components/schemas/BulkDomainResult'
          description: Ordered list of results matching input order (deduplicated)
        summary:
          $ref: '#/components/schemas/BulkDomainSummary'

    Error:
      type: object
      properties:
        error:
          type: string
          description: Machine-readable error code
          example: invalid_domain
        message:
          type: string
          description: Human-readable error message
          example: The provided domain name is not valid.

paths:
  /domain/{domain}:
    get:
      operationId: lookupDomain
      summary: Domain Lookup
      description: |
        Query RDAP registration data for a domain name. Returns normalized data including registrar info, dates, nameservers, status codes, DNSSEC, and contact entities.

        Supports 1,200+ TLDs via the IANA RDAP bootstrap registry.

        Use `?follow=true` to follow the registrar's RDAP link and fetch richer entity data. This is especially useful for thin registries (`.com`, `.net`, `.org`) where the registry only returns registrar info.
      tags:
        - Domain
      parameters:
        - name: domain
          in: path
          required: true
          description: The domain name to look up
          schema:
            type: string
            example: google.com
        - name: follow
          in: query
          required: false
          description: |
            Follow the registrar's RDAP link to fetch richer entity data (registrant, admin, tech contacts).
            Useful for thin registries like `.com` and `.net` where the registry only returns registrar info.
            Adds latency for uncached requests but results are cached normally.
          schema:
            type: boolean
            default: false
      responses:
        '200':
          description: Successful lookup
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DomainResponse'
              examples:
                basic:
                  summary: Basic lookup (.com, no follow)
                  value:
                    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: abusecomplaints@markmonitor.com
                      abuse_phone: "+1.2086851750"
                      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:
                      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"
                followed:
                  summary: Followed lookup (.com, follow=true)
                  value:
                    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: abusecomplaints@markmonitor.com
                      abuse_phone: "+1.2086851750"
                      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:
                        name: null
                        organization: Google LLC
                        email: registrant@google.com
                        phone: "+1.2083851234"
                        address: "1600 Amphitheatre Parkway, Mountain View, CA, 94043"
                        contact_url: null
                        country_code: US
                      administrative:
                        name: null
                        organization: Google LLC
                        email: dns-admin@google.com
                        phone: "+1.2083851234"
                        address: "1600 Amphitheatre Parkway, Mountain View, CA, 94043"
                        contact_url: null
                        country_code: US
                      technical:
                        name: null
                        organization: Google LLC
                        email: dns-admin@google.com
                        phone: "+1.2083851234"
                        address: "1600 Amphitheatre Parkway, Mountain View, CA, 94043"
                        contact_url: null
                        country_code: US
                    meta:
                      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
        '400':
          description: Invalid domain name format
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error: invalid_domain
                message: The provided domain name is not valid.
        '401':
          description: Missing or invalid API key
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error: unauthenticated
                message: Invalid or missing API token.
        '403':
          description: No active subscription
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error: subscription_required
                message: An active subscription is required to use the API. Subscribe at https://rdapapi.io/pricing
        '404':
          description: No RDAP data found for this domain
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error: not_found
                message: "No RDAP data found for domain: nonexistent.example"
        '429':
          description: Rate limit or monthly quota exceeded
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              examples:
                rate_limit:
                  summary: Per-minute rate limit exceeded
                  value:
                    error: rate_limit_exceeded
                    message: Rate limit of 60 requests per minute exceeded.
                quota:
                  summary: Monthly quota exceeded
                  value:
                    error: quota_exceeded
                    message: Monthly request limit of 10000 reached. Upgrade your plan at https://rdapapi.io/pricing
        '502':
          description: Upstream RDAP server error or server temporarily unavailable
          headers:
            Retry-After:
              description: Seconds until the upstream server may recover. Present when the server is known to be down.
              schema:
                type: integer
              required: false
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: lookup_failed
                  message:
                    type: string
                    example: RDAP lookup failed. Please try again later.
                  retry_after:
                    type: integer
                    nullable: true
                    description: Seconds until the upstream server may recover. Null when unknown.
                    example: 60
              example:
                error: lookup_failed
                message: RDAP lookup failed. Please try again later.
                retry_after: 60

  /domains/bulk:
    post:
      operationId: bulkDomainLookup
      summary: Bulk Domain Lookup
      description: |
        Look up multiple domains in a single request with concurrent upstream RDAP fetches.

        Supports up to 10 domains per request. Each domain counts as one request toward your monthly quota.
        Duplicate domains (case-insensitive) are automatically deduplicated.

        **Requires Pro or Business plan.** Starter plan users receive a 403 error.

        Use `follow: true` to follow registrar RDAP links for richer entity data on all domains.

        **Note:** Bulk requests with uncached domains may take 5–15 seconds. Set your client timeout accordingly.
      tags:
        - Domain
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - domains
              properties:
                domains:
                  type: array
                  items:
                    type: string
                  minItems: 1
                  maxItems: 10
                  description: List of domain names to look up (max 10)
                  example:
                    - google.com
                    - github.com
                    - invalid..com
                follow:
                  type: boolean
                  default: false
                  description: Follow registrar RDAP links for richer entity data
      responses:
        '200':
          description: |
            Bulk lookup results. Always returns 200 even if individual domains fail.
            Check each result's `status` field for per-domain success/failure.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BulkDomainResponse'
              example:
                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: abusecomplaints@markmonitor.com
                        abuse_phone: "+1.2086851750"
                        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:
                      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: abusecomplaints@markmonitor.com
                        abuse_phone: "+1.2086851750"
                        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:
                      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
        '401':
          description: Missing or invalid API key
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error: unauthenticated
                message: Invalid or missing API token.
        '403':
          description: No active subscription or plan upgrade required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              examples:
                no_subscription:
                  summary: No active subscription
                  value:
                    error: subscription_required
                    message: An active subscription is required to use the API. Subscribe at https://rdapapi.io/pricing
                starter_plan:
                  summary: Starter plan (upgrade required)
                  value:
                    error: plan_upgrade_required
                    message: Bulk lookups require a Pro or Business plan. Upgrade at https://rdapapi.io/pricing
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string
                    example: The domains field must not have more than 10 items.
                  errors:
                    type: object
                    properties:
                      domains:
                        type: array
                        items:
                          type: string
                    example:
                      domains:
                        - The domains field must not have more than 10 items.
        '429':
          description: Rate limit or monthly quota exceeded
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              examples:
                rate_limit:
                  summary: Per-minute rate limit exceeded
                  value:
                    error: rate_limit_exceeded
                    message: Rate limit of 60 requests per minute exceeded.
                quota:
                  summary: Monthly quota exceeded
                  value:
                    error: quota_exceeded
                    message: Monthly request limit of 10000 reached. Upgrade your plan at https://rdapapi.io/pricing

  /ip/{ip}/{prefix}:
    get:
      operationId: lookupIp
      summary: IP Address Lookup
      description: |
        Query RDAP registration data for an IP address (IPv4 or IPv6). Returns normalized data including network handle, name, address range, CIDR, status codes, and contact entities.

        Optionally include a CIDR prefix length to query a specific network block (e.g. `/ip/8.8.8.0/24`). Different prefix lengths may return different network allocations per RFC 9082.
      tags:
        - IP
      parameters:
        - name: ip
          in: path
          required: true
          description: IPv4 or IPv6 address to look up
          schema:
            type: string
            example: 8.8.8.8
        - name: prefix
          in: path
          required: false
          description: CIDR prefix length (0-32 for IPv4, 0-128 for IPv6). When omitted, the RDAP server returns the most specific allocation for the IP.
          schema:
            type: integer
            minimum: 0
            maximum: 128
            example: 24
      responses:
        '200':
          description: Successful lookup
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/IpResponse'
              example:
                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-28T17:24:33-05:00"
                  expires: null
                  updated: "2023-12-28T17:24:56-05:00"
                entities:
                  registrant:
                    name: Google LLC
                    organization: null
                    email: null
                    phone: null
                    address: null
                    contact_url: null
                    country_code: null
                cidr:
                  - "8.8.8.0/24"
                meta:
                  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"
        '400':
          description: Invalid IP address format
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error: invalid_ip
                message: The provided IP address is not valid.
        '401':
          description: Missing or invalid API key
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error: unauthenticated
                message: Invalid or missing API token.
        '403':
          description: No active subscription
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error: subscription_required
                message: An active subscription is required to use the API. Subscribe at https://rdapapi.io/pricing
        '404':
          description: No RDAP data found for this IP address
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error: not_found
                message: No RDAP data was found for this IP address.
        '429':
          description: Rate limit or monthly quota exceeded
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              examples:
                rate_limit:
                  summary: Per-minute rate limit exceeded
                  value:
                    error: rate_limit_exceeded
                    message: Rate limit of 60 requests per minute exceeded.
                quota:
                  summary: Monthly quota exceeded
                  value:
                    error: quota_exceeded
                    message: Monthly request limit of 10000 reached. Upgrade your plan at https://rdapapi.io/pricing
        '502':
          description: Upstream RDAP server error or server temporarily unavailable
          headers:
            Retry-After:
              description: Seconds until the upstream server may recover. Present when the server is known to be down.
              schema:
                type: integer
              required: false
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: lookup_failed
                  message:
                    type: string
                    example: RDAP lookup failed. Please try again later.
                  retry_after:
                    type: integer
                    nullable: true
                    description: Seconds until the upstream server may recover. Null when unknown.
                    example: 60
              example:
                error: lookup_failed
                message: RDAP lookup failed. Please try again later.
                retry_after: 60

  /asn/{asn}:
    get:
      operationId: lookupAsn
      summary: ASN Lookup
      description: |
        Query RDAP registration data for an Autonomous System Number (ASN). Returns normalized data including handle, name, ASN range, status codes, and contact entities.

        The ASN parameter accepts a plain number (e.g. `15169`) or with the "AS" prefix (e.g. `AS15169`).
      tags:
        - ASN
      parameters:
        - name: asn
          in: path
          required: true
          description: Autonomous System Number (1–4,294,967,295), optionally prefixed with "AS"
          schema:
            type: string
            example: "15169"
      responses:
        '200':
          description: Successful lookup
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AsnResponse'
              example:
                handle: AS15169
                name: GOOGLE
                type: null
                start_autnum: 15169
                end_autnum: 15169
                status:
                  - active
                dates:
                  registered: "2000-03-30T00:00:00-05:00"
                  expires: null
                  updated: "2012-02-24T09:44:34-05:00"
                entities:
                  registrant:
                    name: Google LLC
                    organization: null
                    email: null
                    phone: null
                    address: null
                    contact_url: null
                    country_code: null
                meta:
                  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"
        '400':
          description: Invalid ASN format
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error: invalid_asn
                message: 'The provided ASN is not valid. Use a number between 1 and 4,294,967,295, optionally prefixed with "AS".'
        '401':
          description: Missing or invalid API key
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error: unauthenticated
                message: Invalid or missing API token.
        '403':
          description: No active subscription
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error: subscription_required
                message: An active subscription is required to use the API. Subscribe at https://rdapapi.io/pricing
        '404':
          description: No RDAP data found for this ASN
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error: not_found
                message: No RDAP data was found for this ASN.
        '429':
          description: Rate limit or monthly quota exceeded
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              examples:
                rate_limit:
                  summary: Per-minute rate limit exceeded
                  value:
                    error: rate_limit_exceeded
                    message: Rate limit of 60 requests per minute exceeded.
                quota:
                  summary: Monthly quota exceeded
                  value:
                    error: quota_exceeded
                    message: Monthly request limit of 10000 reached. Upgrade your plan at https://rdapapi.io/pricing
        '502':
          description: Upstream RDAP server error or server temporarily unavailable
          headers:
            Retry-After:
              description: Seconds until the upstream server may recover. Present when the server is known to be down.
              schema:
                type: integer
              required: false
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: lookup_failed
                  message:
                    type: string
                    example: RDAP lookup failed. Please try again later.
                  retry_after:
                    type: integer
                    nullable: true
                    description: Seconds until the upstream server may recover. Null when unknown.
                    example: 60
              example:
                error: lookup_failed
                message: RDAP lookup failed. Please try again later.
                retry_after: 60

  /nameserver/{host}:
    get:
      operationId: lookupNameserver
      summary: Nameserver Lookup
      description: |
        Query RDAP registration data for a nameserver hostname. Returns normalized data including the hostname, IP addresses, status codes, and contact entities.

        Uses the DNS IANA bootstrap registry (same as domain lookups) to discover the authoritative RDAP server.
      tags:
        - Nameserver
      parameters:
        - name: host
          in: path
          required: true
          description: Nameserver hostname to look up
          schema:
            type: string
            example: ns1.google.com
      responses:
        '200':
          description: Successful lookup
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/NameserverResponse'
              example:
                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:
                  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"
        '400':
          description: Invalid nameserver hostname format
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error: invalid_nameserver
                message: The provided nameserver hostname is not valid.
        '401':
          description: Missing or invalid API key
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error: unauthenticated
                message: Invalid or missing API token.
        '403':
          description: No active subscription
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error: subscription_required
                message: An active subscription is required to use the API. Subscribe at https://rdapapi.io/pricing
        '404':
          description: No RDAP data found for this nameserver
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error: not_found
                message: No RDAP data was found for this nameserver.
        '429':
          description: Rate limit or monthly quota exceeded
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              examples:
                rate_limit:
                  summary: Per-minute rate limit exceeded
                  value:
                    error: rate_limit_exceeded
                    message: Rate limit of 60 requests per minute exceeded.
                quota:
                  summary: Monthly quota exceeded
                  value:
                    error: quota_exceeded
                    message: Monthly request limit of 10000 reached. Upgrade your plan at https://rdapapi.io/pricing
        '502':
          description: Upstream RDAP server error or server temporarily unavailable
          headers:
            Retry-After:
              description: Seconds until the upstream server may recover. Present when the server is known to be down.
              schema:
                type: integer
              required: false
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: lookup_failed
                  message:
                    type: string
                    example: RDAP lookup failed. Please try again later.
                  retry_after:
                    type: integer
                    nullable: true
                    description: Seconds until the upstream server may recover. Null when unknown.
                    example: 60
              example:
                error: lookup_failed
                message: RDAP lookup failed. Please try again later.
                retry_after: 60

  /entity/{handle}:
    get:
      operationId: lookupEntity
      summary: Entity Lookup
      description: |
        Query RDAP registration data for an entity (contact/organization) by handle. Returns normalized data including name, organization, contact details, roles, status codes, and nested entities.

        **Supported registries:** ARIN, RIPE NCC, APNIC, LACNIC, and AFRINIC. The RDAP server is resolved from the entity handle suffix (e.g. `-ARIN`, `-RIPE`, `-AP`). Handles without a recognized suffix that match short alphanumeric patterns (e.g. `GOGL`) default to ARIN.
      tags:
        - Entity
      parameters:
        - name: handle
          in: path
          required: true
          description: Entity handle (e.g. GOGL, ABUSE5250-ARIN, ORG-GLLC1-RIPE)
          schema:
            type: string
            example: GOGL
      responses:
        '200':
          description: Successful lookup
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/EntityResponse'
              example:
                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-30T00:00:00-04:00"
                  expires: null
                  updated: "2019-10-31T15:45:45-04:00"
                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: network-abuse@google.com
                    phone: "+1-650-253-0000"
                    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:
                  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"
        '400':
          description: Invalid entity handle format
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error: invalid_handle
                message: The provided entity handle is not valid.
        '401':
          description: Missing or invalid API key
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error: unauthenticated
                message: Invalid or missing API token.
        '403':
          description: No active subscription
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error: subscription_required
                message: An active subscription is required to use the API. Subscribe at https://rdapapi.io/pricing
        '404':
          description: No RDAP data found for this entity
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error: not_found
                message: This entity was not found.
        '429':
          description: Rate limit or monthly quota exceeded
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              examples:
                rate_limit:
                  summary: Per-minute rate limit exceeded
                  value:
                    error: rate_limit_exceeded
                    message: Rate limit of 60 requests per minute exceeded.
                quota:
                  summary: Monthly quota exceeded
                  value:
                    error: quota_exceeded
                    message: Monthly request limit of 10000 reached. Upgrade your plan at https://rdapapi.io/pricing
        '502':
          description: Upstream RDAP server error or server temporarily unavailable
          headers:
            Retry-After:
              description: Seconds until the upstream server may recover. Present when the server is known to be down.
              schema:
                type: integer
              required: false
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: lookup_failed
                  message:
                    type: string
                    example: RDAP lookup failed. Please try again later.
                  retry_after:
                    type: integer
                    nullable: true
                    description: Seconds until the upstream server may recover. Null when unknown.
                    example: 60
              example:
                error: lookup_failed
                message: RDAP lookup failed. Please try again later.
                retry_after: 60
