Skip to content

Parsed Domain RDAP

This feed provides parsed and normalized domain information extracted from raw RDAP records, including contact information, registrar details, name servers, and important dates. It's designed for efficient data searching, indexing, and automated processing in security workflows.

Overview

Domains are apex-level (for example, example.com but not www.example.com), and the feed provides structured, machine-readable RDAP data from both domain registries and registrars.

Use this feed when you need to:

  • Search for, index, or cross-reference data from RDAP records
  • Enable programmatic access to structured RDAP data
  • Analyze domain registration data to identify patterns
  • Track threat actors through registration information
  • Monitor changes in registration data for brand protection
  • Automate domain intelligence workflows

Inclusion criteria: Changes to global domain registration information, populated by the Registration Data Access Protocol (RDAP).

Note: This feed complements the 5-Minute WHOIS Feed as registries and registrars transition from WHOIS to RDAP.

Requirements

You need the following to access Threat Feeds:

  • An Enterprise Account with DomainTools, accessible at https://account.domaintools.com/my-account/
  • Authentication credentials (API key for header authentication, or API username and key for HMAC or open key authentication)
  • A way to interact with a REST API delivered through AWS CloudFront

Obtain your API credentials from your group's API administrator. API administrators can manage their API keys at https://research.domaintools.com, selecting the drop-down account menu and choosing API admin.

For assistance, contact enterprisesupport@domaintools.com.

Authentication

You can authenticate to the Parsed Domain RDAP APIs using three different methods. Choose the method that best fits your security requirements and technical environment.

API key (header) authentication

Authenticate your requests by including the API key in the header of each HTTP request. The API key serves as a unique identifier and authenticates your requests.

Required header:

X-Api-Key: YOUR_API_KEY

Examples:

# Feed API request
curl -H 'X-Api-Key: YOUR_API_KEY' \
  'https://api.domaintools.com/v1/feed/domainrdap/?sessionID=myRDAPMonitor'
# Download API request
curl -H 'X-Api-Key: YOUR_API_KEY' \
  'https://api.domaintools.com/v1/download/domainrdap/'

HMAC authentication

HMAC authentication is a secure alternative to API key-based methods. It requires signing each request with a SHA1 HMAC digest derived from your API secret, providing integrity and authenticity without exposing credentials directly in the request.

This method is recommended for systems where authentication credentials shouldn't be stored in plain text or included directly in request URLs.

DomainTools supports MD5, SHA1, and SHA256 for the hashing algorithm.

Required query parameters:

  • api_username: Your DomainTools API username
  • signature: HMAC-SHA1 signature of api_username + timestamp + uri_path
  • timestamp: Current UTC timestamp in ISO 8601 format (for example, 2025-06-01T15:30:00Z)

Constructing the HMAC signature:

signature = HMAC-SHA1(api_key, api_username + timestamp + uri_path)

URI path must include API version

The uri_path parameter must include the API version prefix. For example, use /v1/feed/nod/ not /feed/nod/.

Example Python signing function:

import hmac
import hashlib

def sign(api_username, api_key, timestamp, uri):
    params = f"{api_username}{timestamp}{uri}"
    return hmac.new(api_key.encode("utf-8"), params.encode("utf-8"), hashlib.sha1).hexdigest()

HMAC timestamp requirements

The timestamp parameter in HMAC authentication must be current (within a few minutes of the server time). The timestamps shown in these examples are static for demonstration purposes. In production, generate a fresh timestamp for each request using your system's current time in ISO 8601 UTC format (e.g., 2025-01-06T15:30:00Z).

Examples:

# Feed API request with HMAC
curl 'https://api.domaintools.com/v1/feed/domainrdap/?api_username=YOUR_USERNAME&signature=HMAC_SIGNATURE&timestamp=2025-01-06T15:30:00Z&sessionID=myRDAPMonitor'
# Download API request with HMAC
curl 'https://api.domaintools.com/v1/download/domainrdap/?api_username=YOUR_USERNAME&signature=HMAC_SIGNATURE&timestamp=2025-01-06T15:30:00Z'

Open key authentication

This is the easiest authentication scheme to implement, but also the least secure. Each request contains the full API key and API username as query parameters. We recommend using API key header authentication or HMAC authentication instead.

If you're unsure about your authentication options, contact enterprisesupport@domaintools.com.

Required query parameters:

  • api_username: Your API username
  • api_key: Your API key

Examples:

# Feed API request
curl 'https://api.domaintools.com/v1/feed/domainrdap/?api_username=YOUR_USERNAME&api_key=YOUR_API_KEY&sessionID=myRDAPMonitor'
# Download API request
curl 'https://api.domaintools.com/v1/download/domainrdap/?api_username=YOUR_USERNAME&api_key=YOUR_API_KEY'

Real-time Feed API

The Feed API provides real-time access to current Parsed Domain RDAP data. Use this API to poll for the latest feed updates at regular intervals, maintain a session to track your position in the feed, and filter results based on your specific needs.

Important: The Parsed Domain RDAP feed returns JSON format only and does not support CSV format.

Base URL

https://api.domaintools.com/v1/feed/domainrdap/

Rate limits

Real-time feeds have the following rate limits:

  • 2 queries per minute
  • 120 queries per hour

If you exceed these limits, the API returns an error.

Response formats

The Parsed Domain RDAP feed returns responses in JSON format only.

Accept: application/json (default): Returns JSON format. This is the only supported format for this feed.

Note: Unlike other feeds, the Parsed Domain RDAP feed does not support CSV format (text/csv).

Session management

Session management allows you to maintain your position in the feed data stream, ensuring you don't miss or duplicate events when polling the API.

How sessions work:

  • Start a new session: Provide a unique sessionID parameter of your choosing. By default, the API returns the past hour of results.
  • Resume a session: Use the same sessionID in subsequent requests. The API returns all data since your last request.
  • Handle large result sets: If a single request exceeds 10M results, the API returns an HTTP 206 response code. Repeat the same request with the same sessionID to receive the next batch of data until you receive an HTTP 200 response code.
  • Delete a session: Use an HTTP DELETE request with your sessionID to clear the saved offset and start fresh.

Session ID requirements:

  • 1 to 64 characters in length
  • Alphanumeric characters and hyphens only ([a-zA-Z0-9-]+)
  • Case-sensitive

Quick start

The standard access pattern is to periodically request the most recent feed data, as often as every 60 seconds.

curl -H 'X-Api-Key: YOUR_API_KEY' \
  'https://api.domaintools.com/v1/feed/domainrdap/?sessionID=myRDAPMonitor'

This starts a new session and returns the last hour of data. Subsequent calls with the same sessionID return data since the last request.

Parameters

sessionID

Type: String

Valid values: 1-64 alphanumeric characters and hyphens ([a-zA-Z0-9-]+)

Description: A unique identifier for the session, used for resuming data retrieval from the last point. Use a new sessionID to begin a new session, fetching the most recent hour by default. Reuse the same sessionID to return all feed data since your last request. If omitted, time window parameters (such as after/before) are required.

Example: sessionID=mySOC

Required: Yes, to continue where you left off (or use after/before instead)

after

Type: Integer or string

Valid values:

  • Integer: -1 to -432,000 (relative seconds before current time)
  • String: ISO 8601 datetime in UTC format (YYYY-MM-DDTHH:MM:SSZ)

Description: The start of the query window (inclusive). When using an integer, the value is in seconds relative to the current time. When using a string, provide an absolute timestamp. The timestamp must represent a point between 1 second ago and 5 days ago, relative to the current UTC time.

Example: after=-60 or after=2024-10-16T10:20:00Z

Required: Yes, if before or sessionID not provided

before

Type: Integer or string

Valid values:

  • Integer: -1 to -432,000 (relative seconds before current time)
  • String: ISO 8601 datetime in UTC format (YYYY-MM-DDTHH:MM:SSZ)

Description: The end of the query window (inclusive). When using an integer, the value is in seconds relative to the current time. When using a string, provide an absolute timestamp. The timestamp must represent a point between 1 second ago and 5 days ago, relative to the current UTC time.

Example: before=-120 or before=2024-10-16T10:20:00Z

Required: Yes, if after or sessionID not provided

domain

Type: String

Valid values: Domain character set restricted by the DNS specification (letters, digits, hyphens). International characters should be specified in punycode. A trailing dot is acceptable.

Description: Filter for an exact domain or a domain substring by prefixing or suffixing your string with *. Multiple parameters are supported (for example, ?domain=*apple*&domain=*microsoft*). The URL-encoded version of * (%2A) may be required in some clients.

Example: domain=*bank* or domain=example.com

Required: No

fromBeginning

Type: Boolean

Valid values: true

Description: Functions with new session IDs to return the first hour (rather than the last). Returns an error if the session ID already exists. Only the value true is accepted; any other value (including false) will be ignored or treated as omitted.

Example: fromBeginning=true

Required: No

top

Type: Integer

Valid values: Positive integer, 1-1,000,000,000

Description: Limits the number of results in the response payload. Primarily intended for testing. When you apply this parameter to risk feeds, results are sorted by overall_risk (descending).

Example: top=10

Required: No

Response structure

The API returns JSON format (not NDJSON) with one record per response.

Note: The Parsed Domain RDAP feed does not support CSV format. Only JSON responses are available.

Response fields:

timestamp (string): ISO 8601 UTC timestamp when the domain was observed

domain (string): The apex-level domain name

raw_record (object): Contains the original raw RDAP responses from both registry and registrar

  • first_request_timestamp (string): When the first RDAP request was made
  • requests (array): Array of RDAP request/response pairs
  • data (string): JSON-encoded string of the raw RDAP record
  • source_type (string): Either "registry" or "registrar"
  • timestamp (string): When this request was made
  • url (string): The RDAP endpoint URL queried

parsed_record (object): Parsed and normalized domain information

  • parsed_fields (object): Structured data extracted from RDAP records, may include:
  • domain: Domain name
  • handle: Registry/registrar handle
  • creation_date: When the domain was created
  • expiration_date: When the domain expires
  • last_changed_date: Last modification date
  • dnssec: DNSSEC status
  • domain_statuses: Array of domain status codes
  • nameservers: Array of nameserver hostnames
  • contacts: Contact information (registrant, admin, tech)
  • registrar: Registrar information
  • links: Related RDAP links
  • conformance: RDAP conformance levels
  • email_domains: Extracted email domains
  • emails: Contact email addresses
  • And more, depending on the registry
  • registrar_request_url (string, nullable): URL of the registrar RDAP endpoint
  • registry_request_url (string, nullable): URL of the registry RDAP endpoint

Example response:

{
  "timestamp": "2025-01-06T15:30:42Z",
  "domain": "example.com",
  "raw_record": {
    "first_request_timestamp": "2025-01-06T15:30:40Z",
    "requests": [
      {
        "data": "{\"rdapConformance\":[\"rdap_level_0\"],...}",
        "source_type": "registry",
        "timestamp": "2025-01-06T15:30:40Z",
        "url": "https://rdap.verisign.com/com/v1/domain/example.com"
      }
    ]
  },
  "parsed_record": {
    "parsed_fields": {
      "domain": "example.com",
      "creation_date": "1995-08-14T04:00:00Z",
      "expiration_date": "2026-08-13T04:00:00Z",
      "nameservers": ["a.iana-servers.net", "b.iana-servers.net"]
    },
    "registry_request_url": "https://rdap.verisign.com/com/v1/domain/example.com",
    "registrar_request_url": null
  }
}

Response codes

Code Status Description
200 OK The request was successful and all data has been delivered
206 Partial content The request was successful, but only a portion of the data was returned. The request exceeded 10M results or the 1-hour evaluation window. Repeat the same request with the same sessionID to receive the next batch of data until you receive an HTTP 200 response
400 Bad request The request is malformed
403 Forbidden Missing or invalid API credentials
404 Not found The requested resource (such as a sessionID) doesn't exist
406 Not acceptable The specified Accept header value isn't supported. Only application/x-ndjson and text/csv are accepted
422 Unprocessable entity The request is syntactically valid but violates semantic or domain-specific rules (for example, invalid query parameter values)

Examples

Basic session polling:

# Start a new session
curl -H 'X-Api-Key: YOUR_API_KEY' \
  'https://api.domaintools.com/v1/feed/domainrdap/?sessionID=myRDAPMonitor'
# Resume the session (returns data since last request)
curl -H 'X-Api-Key: YOUR_API_KEY' \
  'https://api.domaintools.com/v1/feed/domainrdap/?sessionID=myRDAPMonitor'

Time window filtering:

# Get data from a specific time range
curl -H 'X-Api-Key: YOUR_API_KEY' \
  'https://api.domaintools.com/v1/feed/domainrdap/?after=2025-01-06T10:00:00Z&before=2025-01-06T11:00:00Z'

Domain filtering:

# Filter for specific domain patterns
curl -H 'X-Api-Key: YOUR_API_KEY' \
  'https://api.domaintools.com/v1/feed/domainrdap/?domain=*.example.com&sessionID=myRDAPMonitor'

Limit results for testing:

# Get only the first result for testing
curl -H 'X-Api-Key: YOUR_API_KEY' \
  'https://api.domaintools.com/v1/feed/domainrdap/?top=1&sessionID=myRDAPMonitor'

Handling large result sets:

# If you receive HTTP 206, repeat the request to get the next batch
curl -H 'X-Api-Key: YOUR_API_KEY' \
  'https://api.domaintools.com/v1/feed/domainrdap/?sessionID=myRDAPMonitor'
# Repeat until you receive HTTP 200
curl -H 'X-Api-Key: YOUR_API_KEY' \
  'https://api.domaintools.com/v1/feed/domainrdap/?sessionID=myRDAPMonitor'

Delete a session:

# Clear the saved offset and start fresh
curl -X DELETE -H 'X-Api-Key: YOUR_API_KEY' \
  'https://api.domaintools.com/v1/feed/domainrdap/?sessionID=myRDAPMonitor'

Real-time Download API

The Real-time Download API provides access to historical Parsed Domain RDAP data through temporary AWS S3 file links. Use this API to retrieve archived data you may have missed or to backfill your systems with historical information. Files are organized by hour and available for 90 days.

Base URL

https://api.domaintools.com/v1/download/domainrdap/

Parameters

limit

Type: Integer

Valid values: Positive integer

Description: Limits the number of files returned in the response, starting from the most recent. Use to control payload size or test specific cases.

Example: limit=10

Required: No

Response structure

The API returns a JSON response containing an array of downloadable files. Each file entry includes:

download_name (string): The feed identifier (domainrdap)

files (array): List of downloadable file entries

Each file object contains:

  • name (string): Path and filename of the downloadable file
  • last_modified (string): Timestamp of last modification in ISO 8601 UTC format
  • etag (string): ETag (hash) used to verify file identity and versioning
  • size (integer): File size in bytes
  • url (string): Temporary signed URL to download the file from AWS CloudFront

File naming convention:

  • Data file: domainrdap/{YYYY-MM-DD}/domainrdap-{YYYYMMDD}.{HH00}-{HH00}.json.gz
  • Checksum file: domainrdap/{YYYY-MM-DD}/domainrdap-{YYYYMMDD}.{HH00}-{HH00}.json.gz.sha256

Example response:

{
  "response": {
    "download_name": "domainrdap",
    "files": [
      {
        "name": "domainrdap/2024-11-19/domainrdap-20241119.1900-2000.json.gz.sha256",
        "last_modified": "2024-11-19T20:00:11+00:00",
        "etag": "\"67a6d9b0973b2d31ffb779dc8f7f8cfa\"",
        "size": 64,
        "url": "https://download.example.com/domainrdap/2024-11-19/domainrdap-20241119.1900-2000.json.gz.sha256?Expires=..."
      },
      {
        "name": "domainrdap/2024-11-19/domainrdap-20241119.1900-2000.json.gz",
        "last_modified": "2024-11-19T20:00:11+00:00",
        "etag": "\"67a6d9b0973b2d31ffb779dc8f7f8cfa\"",
        "size": 1850000,
        "url": "https://download.example.com/domainrdap/2024-11-19/domainrdap-20241119.1900-2000.json.gz?Expires=..."
      }
    ]
  }
}

Response codes

Code Status Description
200 OK The request was successful
400 Bad request The request is malformed
403 Forbidden Missing or invalid API credentials
422 Unprocessable entity The request is syntactically valid but violates semantic or domain-specific rules (for example, invalid query parameter values)

File contents

The *.json.gz.sha256 file is a checksum containing a SHA-256 hash value used to verify the integrity of the downloaded file.

The *.json.gz file, when uncompressed, contains JSON data in the same format as the Feed API response (JSON with timestamp, domain, raw_record, and parsed_record fields).

Examples

List available files:

# Get the most recent files
curl -H 'X-Api-Key: YOUR_API_KEY' \
  'https://api.domaintools.com/v1/download/domainrdap/?limit=10'

Download and verify a file:

# Get the file list
curl -H 'X-Api-Key: YOUR_API_KEY' \
  'https://api.domaintools.com/v1/download/domainrdap/?limit=2' > files.json

# Extract the URL and download the data file
curl -o domainrdap-data.json.gz "$(jq -r '.response.files[1].url' files.json)"

# Download the checksum file
curl -o domainrdap-data.json.gz.sha256 "$(jq -r '.response.files[0].url' files.json)"

# Verify the integrity
sha256sum -c domainrdap-data.json.gz.sha256

Batch processing:

# Download multiple files in a loop
for url in $(curl -H 'X-Api-Key: YOUR_API_KEY' \
  'https://api.domaintools.com/v1/download/domainrdap/?limit=24' | \
  jq -r '.response.files[].url' | grep '\.json\.gz$'); do
  curl -O "$url"
done