Real-Time Threat Feeds User Guide¶
Introduction¶
Real-Time Threat Feeds provide data on the different stages of the domain lifecycle: from first-observed in the wild to newly re-activated after a period of quiet. You can access current feed data in real-time or retrieve historical feed data through separate APIs. Some feeds also offer data for DNS firewalls in Response Policy Zone (RPZ) format.
Summary of Common Features¶
- Stable, static URL endpoint: fetch the latest feed data with the same query parameters.
- Configurable polling frequency: fetch as often as you like, up to every 60 seconds.
- 5-day data retention time for Feed API: current feed data is easily accessible.
- Access historical data via Download API: never lose out on data missed accidentally.
- Session management: Pick up where you left off, without missing or duplicating events.
- Domain pattern filtering: Use the
domainquery parameter to filter a feed based on domain name patterns that are important to you, without extra downstream data processing.
Feed Descriptions and URLs¶
More feeds are becoming available. Contact enterprisesupport@domaintools.com to learn more.
Domain Discovery¶
New domains as they're discovered in domain registration information, observed by our global passive DNS sensor network, or reported by trusted third parties.
Feed endpoint: api.domaintools.com/v1/feed/domaindiscovery/
Download endpoint: api.domaintools.com/v1/download/domaindiscovery/
Jump to: Authentication | Feed API | Download API
Domain Hotlist¶
Domains with high Domain Risk Scores that have also been active within 24 hours.
Each entry in the Domain Hotlist is an apex-level domain. The feed emits domains when both of these conditions are met within a 24-hour period:
- Observed by passive DNS
- Assigned a Domain Risk Score of ≥70 Proximity OR ≥90 Phish OR ≥90 Malware OR ≥90 Spam
Domain Risk Scores have an expiration time of 24 hours:
- When a domain receives a high Domain Risk Score and activity was observed in passive DNS over the previous 24 hours, the feed emits the domain immediately with a 24-hour expiration time. (This expiration time is 24 hours after the first of either of those events.)
- If a domain receives a high Domain Risk Score but has no passive DNS activity over the past 24 hours, the system waits for the Domain Risk Score's 24-hour period. If passive DNS activity is observed on a domain that already has a high and live (not expired) Domain Risk Score, the feed emits the domain with an expiration time of 24 hours from the original risk observation.
- The feed doesn't emit risky domains without passive DNS activity.
The Domain Hotlist includes an expires response field with the expiration time in UTC. We consider the score invalid after 24 hours. We recommend that you delete expired scores or exclude them from detections or queries.
Feed endpoint: api.domaintools.com/v1/feed/domainhotlist/
Download endpoint: api.domaintools.com/v1/download/domainhotlist/
Jump to: Authentication | Feed API | Download API
Domain Risk¶
Real-time updates to Domain Risk Scores for apex domains, regardless of observed traffic.
The feed emits domains at the moment they reach a combined Domain Risk Score of 70+.
We recommend that you stop using Domain Risk entries older than 24 hours (check the timestamp value). The domainrisk feed doesn't have the expires field.
Feed endpoint: api.domaintools.com/v1/feed/domainrisk/
Download endpoint: api.domaintools.com/v1/download/domainrisk/
Jump to: Authentication | Feed API | Download API
Newly Active Domains (NAD)¶
Domains observed in passive DNS to be newly active in the latest lifecycle of the domain: either for the first time or after an inactive period of at least 10 days.
Domains are apex-level (for example, example.com but not www.example.com), and the feed emits them as they're observed.
Feed endpoint: api.domaintools.com/v1/feed/nad/
Download endpoint: api.domaintools.com/v1/download/nad/
Jump to: Authentication | Feed API | Download API
Newly Observed Domains (NOD)¶
Domains observed for the first time in passive DNS.
Domains are apex-level (for example, example.com but not www.example.com), and the feed emits them as they're observed.
Feed endpoint: api.domaintools.com/v1/feed/nod/
Download endpoint: api.domaintools.com/v1/download/nod/
Jump to: Authentication | Feed API | Download API
Newly Observed Hostnames (NOH)¶
Hostname resolutions that we observe for the first time with our global passive DNS sensor network.
The feed emits hostnames as they're observed.
Feed endpoint: api.domaintools.com/v1/feed/noh/
Download endpoint: api.domaintools.com/v1/download/noh/
Jump to: Authentication | Feed API | Download API
Parsed Domain RDAP¶
Changes to global domain registration information, populated by the Registration Data Access Protocol (RDAP). This feed complements the 5-Minute WHOIS Feed as registries and registrars switch from WHOIS to RDAP.
Feed endpoint: api.domaintools.com/v1/feed/domainrdap/
Download endpoint: api.domaintools.com/v1/download/domainrdap/
Jump to: Authentication | Feed API | Download API
The Domain RDAP feed doesn't accept the text/csv Accept header.
Summary of Access Methods¶
- Real-time Feed API: Returns results based on absolute or relative times. See the Feed API Quick Start, authentication, and Feed API sections.
- Download API: The download API returns archives of past results as signed, temporary AWS S3 file links. See the Download API Quick Start, authentication, and Download API sections.
- Response Policy Zone (RPZ): Feed contents delivered as real-time Response Policy Zones that populate DNS firewalls. See the Response Policy Zone section. The following feeds are currently available by RPZ: Newly Active Domains, Newly Observed Domains.
Getting Started¶
Authentication Quick Start¶
You can authenticate with either API Header or API Key and Secret methods. The following example shows API header authentication using curl and a sessionID called mySIEM. By default, the API returns one hour of results:
To authenticate with the API Key and Secret method, provide your api_username and api_key as query parameters. The following example uses curl with the same sessionID (mySIEM):
curl 'https://api.domaintools.com/v1/feed/nod/?api_key=MY_API_KEY&api_username=MY_API_USERNAME&sessionID=mySIEM'
Feed API Quick Start¶
The Feed API standard access pattern is to periodically request the most recent feed data, as often as every 60 seconds. Specify the range of data you receive in one of two ways:
- With
sessionID: Make a call and provide a newsessionIDparameter of your choosing. By default, the API returns the past hour of results.- Each subsequent call to the API using your
sessionIDreturns all data since the last call. - You can maintain only one
sessionIDat a time per account. - Any single request returns a maximum of 10M results. Requests that exceed 10M results return an HTTP
206response code. Repeat the same request (with the samesessionID) to receive the next tranche of data until you receive an HTTP200response code. - You can delete this session ID to clear the saved offset by using an HTTP
DELETEcall.
- Each subsequent call to the API using your
- Or specify the time range in one of two ways:
- Use an
after=-60query parameter, where (in this example)-60indicates the previous 60 seconds. - Use
afterandbeforequery parameters for a time range, with each parameter accepting an ISO-8601 UTC formatted timestamp (a UTC date and time of the formatYYYY-MM-DDThh:mm:ssZ).
- Use an
Optional details:
- The default response format is Newline-Delineated JSON (NDJSON), also known as JSON lines.
- To enable CSV format responses, set the Accept header to
text/csv. You can also add&headers=1to the query parameters to include column headers as the first line in the response. The Parsed Domain RDAP Feed doesn't supporttext/csv.
- To enable CSV format responses, set the Accept header to
- To limit the response payload for testing, add a
top=Nquery parameter, whereNis the number of results to return. - To add server-side domain filtering, use the
domainquery parameter to return a specific domain or domains where a specific substring is present.- Exact match example:
domain=example.com - Partial match example:
domain=*example* - Sometimes you'll need to URL-encode the asterisk to
%2Adepending on the method used to query. In acurlcommand, you can use an asterisk (*) if you single-quote the URL.
- Exact match example:
Download API Quick Start¶
The Download API returns short-lived, signed URLs for pairs of files containing historical feed data that change each hour. The {feed_short_name} is one of: nod, nad, noh, domaindiscovery, domainhotlist, domainrisk, or domainrdap:
- A data file:
{feed_short_name}/{YYYY-MM-DD}/{feed_short_name}-{YYYYMMDD}.{starthour:HH00}-{endhour:HH00}.json.gz - A checksum file:
{feed_short_name}/{YYYY-MM-DD}/{feed_short_name}-{YYYYMMDD}.{starthour:HH00}-{endhour:HH00}.json.gz.sha256
Here is an example curl command to retrieve the list of NOD files available to download:
Requirements¶
You will require a license to one or more DomainTools feeds, and API credentials. Your required API credentials will vary with your authentication method, detailed below.
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.
Usage Limits¶
Real-time feeds have the following rate limits:
- 2 queries per minute
- 120 queries per hour
Exceeding these limits will cause the API to return an error.
Connection Speed¶
For optimal performance, we recommend the following connection speeds:
- 10 Mbps (1.25 MB/s): For most feeds with typical use.
- 100 Mbps (12.5 MB/s) or greater: For higher-volume feeds and heavy use.
(Mbps = megabits per second) (MB/s = megabytes per second)
Authentication¶
Authentication is available via HTTP header, HMAC, or API key and secret. If you need to obtain credentials or are unsure about your authentication options, please contact enterprisesupport@domaintools.com.
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 is used to authenticate your requests.
Required API Key Authentication Parameters¶
| Required Parameters | Value |
|---|---|
X-Api-Key |
MY_API_KEY |
Example Request with API Key Authentication¶
curl -H 'X-Api-Key: MY_API_KEY' 'https://api.domaintools.com/v1/feed/nod/?after=-60
HMAC Signature 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 should not be stored in plain text or included directly in request URLs.
| Required Parameters | Value |
|---|---|
api_key |
API Key |
api_username |
API Username |
signature |
HMAC-SHA1 signature of api_username, timestamp, and request path |
timestamp |
ISO 8601 formatted UTC time (e.g., 2025-06-01T15:30:00Z) |
Constructing the HMAC Signature¶
The HMAC signature is computed as follows:
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()
Example Python HMAC request:
import os
import datetime
import urllib.parse
import requests
api_username = os.environ["API_USERNAME"]
api_key = os.environ["API_KEY"]
uri = "/v1/feed/nod/"
host = os.environ.get("HOST", "https://api.domaintools.com/")
timestamp = datetime.datetime.now(datetime.timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")
signature = sign(api_username, api_key, timestamp, uri)
response = requests.get(
urllib.parse.urljoin(host, uri),
params={
"api_username": api_username,
"signature": signature,
"timestamp": timestamp,
"sessionID": "mySIEM", # required parameter for queries
"top": 1 # returns a single result, for testing
},
)
API Key and Secret Authentication¶
This is the easiest and most insecure authentication scheme to implement: each request contains the full API key and API secret. DomainTools typically recommends using API Header authentication instead. If you are unsure about your authentication options, please contact enterprisesupport@domaintools.com.
Required Parameters for API Key and Secret¶
| Required Parameters | Value |
|---|---|
api_username |
API username |
api_key |
API key |
Example Request with API Key and Secret¶
Response Policy Zone (RPZ) Authentication¶
RPZ authentication is detailed in the Response Policy Zone section, below.
Feed API¶
Feed API Base URL¶
Feed API Endpoints¶
| Feed | API Feed Endpoint |
|---|---|
| Domain Discovery | domaindiscovery |
| Domain Hotlist | domainhotlist |
| Domain RDAP | domainrdap |
| Domain Risk | domainrisk |
| Newly Active Domains | nad |
| Newly Observed Domains | nod |
| Newly Observed Hostnames | noh |
Feed API Header Options¶
If the Accept header is omitted, the API returns results in JSON Lines format (application/x-ndjson).
The Accept header is supported for clients who wish to specify the response format explicitly:
| Key | Value | Description |
|---|---|---|
Accept |
application/x-ndjson |
Get results in JSON Lines format. |
Accept |
text/csv |
Get results in CSV format. Not available with the Download API, or in the domainrdap Feed API endpoint. Optionally adding &headers=1 to the query parameters will include column headers as the first line in the response. |
Note that the text/csv Accept header is not accepted by the Domain RDAP feed.
Feed API Common GET Request Parameters¶
| Name | Type | Valid Values | Description | Example | Required | Feeds |
|---|---|---|---|---|---|---|
after |
integer | -1 to -432,000 | The start of the query window in seconds, relative to the current time, inclusive. | after=-60 |
Required if before or sessionID not provided. |
all |
after |
string | ISO 8601 datetime string in UTC form | The start of the query window, inclusive. | after=2024-10-16T10:20:00Z |
Required if before or sessionID not provided. |
all |
before |
integer | -1 to -432,000 | The end of the query window in seconds, relative to the current time, inclusive. | before=-120 |
Required if after or sessionID not provided. |
all |
before |
string | ISO 8601 datetime string in UTC form | The end of the query window. | before=2024-10-16T10:20:00Z |
Required if after or sessionID not provided. |
all |
domain |
string | Domain character set restricted by the DNS specification (Letters, Digits, Hyphens). International characters should be specified in punycode. A trailing dot is acceptable. Multiple domain filters are accepted in a request. |
Filter for an exact domain or a domain substring by prefixing or suffixing your string with *. Multiple parameters are supported. The URL-encoded version of * (%2A) may be required. |
domain=*apple*&domain=*microsoft* |
No | all |
fromBeginning |
boolean | true, false |
Functions with new Session IDs to return the first hour (rather than the last). Returns an error if Session ID already exists. | fromBeginning=true |
No | all |
headers |
boolean | 0, 1 |
Adds a header to the first line of response when text/csv is set in header parameters. |
headers=1 |
No | all |
malware_min |
integer | 1-99 | Filter domains for malware domain risk scores greater than or equal to this value. | malware_min=75 |
No | Domain Hotlist, Domain Risk |
overall_min |
integer | 1-99 | Filter domains for overall domain risk scores greater than or equal to this value. | overall_min=75 |
No | Domain Hotlist, Domain Risk |
phishing_min |
integer | 1-99 | Filter domains for phishing domain risk scores | phishing_min=75 |
No | Domain Hotlist, Domain Risk |
proximity_min |
integer | 1-99 | Filter domains for proximity domain risk scores | proximity_min=75 |
No | Domain Hotlist, Domain Risk |
sessionID |
string | 1-64 alphanumeric characters ([a-zA-Z0-9-]+). |
A string that serves as a unique identifier for the session, used for resuming data retrieval from the last point. | sessionID=mySIEM |
Required to continue where you left off. | all |
spam_min |
integer | 1-99 | Filter domains for spam domain risk score | spam_min=75 |
No | Domain Hotlist, Domain Risk |
top |
integer | Positive integer, 1-1,000,000,000. | Limits the number of results in the response payload. When applied to domainrisk, results are sorted by overall_risk (desc). |
top=10 |
No | all |
Feed API Common DELETE Request Parameters¶
| Name | Type | Valid Values | Description | Examples | Required |
|---|---|---|---|---|---|
sessionID |
string | 1-64 alphanumeric characters ([a-zA-Z0-9-]+). |
A string that serves as a unique identifier for the session, used for resuming data retrieval from the last point. | sessionID=mySIEM |
No |
Feed API Query Examples¶
Use curl and header authentication to retrieve the last 60 seconds of Newly Observed Domains:
curl -H 'X-Api-Key: MY_API_KEY' 'https://api.domaintools.com/v1/feed/nod/?after=-60'
Use curl and header authentication to retrieve the last 4 hours of Newly Observed Domains that contain the keyword bank:
curl -H 'X-Api-Key: MY_API_KEY' 'https://api.domaintools.com/v1/feed/nod/?after=-14400&domain=*bank*'
Feed API Response Codes¶
| Code | Description |
|---|---|
200 |
OK: The request was successful. |
206 |
Partial content: The request was successful, but only a portion of the data was returned. |
400 |
Malformed request |
401 |
Unauthorized |
403 |
Forbidden |
404 |
sessionID does not exist |
406 |
Not Acceptable: The specified Accept header value is not supported. Only application/x-ndjson and text/csv are accepted. |
422 |
Invalid header query parameter |
If an API call returns a HTTP 206 response, continue submitting the same request (with the same sessionID) until the API returns a HTTP 200, signalling that all the data for the request has been delivered.
Feed API Response Structure and Examples¶
NAD, NOD, NOH, and Domain Discovery Response Structure¶
NAD, NOD, NOH, and Domain Discovery return one hour of results by default.
Responses are returned in JSON-lines (JSONL), with each response containing one domain entry per line. Each entry contains a timestamp in ISO 8601 UTC form, and the domain.
| Name | Type | Valid Values | Description | Example |
|---|---|---|---|---|
domain |
str | Domain character set restricted by the DNS specification (Letters, Digits, Hyphens) | Apex-level domain for NAD, NOD, and Domain Discovery. The NOH feed returns full hostnames (e.g., including subdomains.). | "domain":"example.com" |
timestamp |
str | ISO 8601 datetime string in UTC form | Discovery timestamp | "timestamp":"2024-11-15T16:14:39Z" |
Example response:
{"timestamp":"2024-11-15T16:14:39Z","domain":"domiantools.com"}
{"timestamp":"2024-11-15T16:14:38Z","domain":"domsintools.com"}
{"timestamp":"2024-11-15T16:14:36Z","domain":"edomaintools.com"}
{"timestamp":"2024-11-15T16:14:35Z","domain":"omaintools.com"}
{"timestamp":"2024-11-15T16:14:35Z","domain":"v-domaintools.com"}
Domain Hotlist Response Structure¶
The Domain Hotlist returns 1 hour of results by default. Null values are emitted.
Responses are returned in JSON-lines (JSONL), with each response containing one domain entry per line. In addition to the domain and timestamp parameters, the Domain Hotlist and Domain Risk Feeds include risk scoring:
| Name | Type | Valid Values | Description | Example |
|---|---|---|---|---|
timestamp |
str | ISO 8601 UTC timestamp | The date and time of discovery in UTC | "timestamp"="2024-11-15T16:14:39Z" |
domain |
str | Domain character set restricted by the DNS specification (Letters, Digits, Hyphens). | Apex-level domain for NAD, NOD, and Domain Discovery. The NOH feed returns full hostnames (e.g., including subdomains.). | "domain"="example.com" |
phishing_risk |
int | 0-100 | null | Phishing domain risk score | phishing_risk=80 |
malware_risk |
int | 0-100 | null | Malware domain risk score | malware_risk=80 |
spam_risk |
int | 0-100 | null | Spam domain risk score | spam_risk=80 |
proximity_risk |
int | 0-100 | Proximity domain risk score | proximity_risk=80 |
overall_risk |
int | 0-100 | null | Overall domain risk score | overall_risk=80 |
expires |
str | ISO 8601 UTC timestamp | The expiration of the entry. The expiration is 24 hours after the first of the two required events (risk or activity) is detected. | "expires":"2025-08-19T19:08:58Z" |
Example response via api.domaintools.com/v1/feed/domainhotlist?sessionID=mySOC&top=3 (with header authorization):
{"timestamp":"2025-08-18T19:16:47Z","domain":"domiantools.com","phishing_risk":99,"malware_risk":99,"spam_risk":99,"proximity_risk":99,"overall_risk":99,"expires":"2025-08-19T19:08:58Z"}
{"timestamp":"2025-08-18T19:27:56Z","domain":"domsintools.com","phishing_risk":99,"malware_risk":99,"spam_risk":99,"proximity_risk":99,"overall_risk":99,"expires":"2025-08-19T19:23:30Z"}
{"timestamp":"2025-08-18T18:52:12Z","domain":"edomaintools.com","phishing_risk":99,"malware_risk":99,"spam_risk":99,"proximity_risk":99,"overall_risk":99,"expires":"2025-08-19T18:44:51Z"}
Domain Risk Response Structure¶
The Domain Risk Feed returns one hour of results by default. Null values are emitted.
Responses are returned in JSON-lines (JSONL), with each response containing one domain entry per line. In addition to the domain and timestamp parameters, the Domain Hotlist and Domain Risk Feeds include risk scoring:
| Name | Type | Valid Values | Description | Example |
|---|---|---|---|---|
timestamp |
str | ISO 8601 UTC timestamp | The date and time of discovery in UTC | "timestamp"="2024-11-15T16:14:39Z" |
domain |
str | Domain character set restricted by the DNS specification (Letters, Digits, Hyphens) | Apex-level domain for NAD, NOD, and Domain Discovery. The NOH feed returns full hostnames (e.g., including subdomains.). | "domain"="example.com" |
phishing_risk |
int | 0-100 | null | Phishing domain risk score | phishing_risk=80 |
malware_risk |
int | 0-100 | null | Malware domain risk score | malware_risk=80 |
spam_risk |
int | 0-100 | null | Spam domain risk score | spam_risk=80 |
proximity_risk |
int | 0-100 | Proximity domain risk score | proximity_risk=80 |
overall_risk |
int | 0-100 | null | Overall domain risk score | overall_risk=80 |
Example response via api.domaintools.com/v1/feed/domainrisk?sessionID=mySOC&top=3 (with header authorization):
{"timestamp":"2025-04-22T16:08:33Z","domain":"omaintools.com","phishing_risk":94,"malware_risk":88,"spam_risk":93,"proximity_risk":80,"overall_risk":94}
{"timestamp":"2025-04-22T16:08:29Z","domain":"v-domaintools.com","phishing_risk":96,"malware_risk":91,"spam_risk":99,"proximity_risk":85,"overall_risk":99}
{"timestamp":"2025-04-22T16:08:34Z","domain":"domanitools.com","phishing_risk":98,"malware_risk":97,"spam_risk":68,"proximity_risk":72,"overall_risk":98}
Domain RDAP Response Structure¶
The Parsed Domain RDAP feed returns one hour of results by default.
Responses are returned in JSON (not NDJSON). Note that the text/csv Accept header is not accepted by the Domain RDAP feed.
Domain RDAP records for a given domain may be provided by a domain registry, registrar, or both. Domain registries maintain authoritative information about one or more top-level domains (e.g., .com), while domain registrars manage apex domains (e.g., domaintools.com). When domain information is present from both the registry and registrar, this API presents a record containing both sets of results, as well the original raw JSON record, from both the registry and registrar.
Each response begins with either the raw registrar record, the raw registry record, or when useful information is present in both records, the response will contain both the registrar and registry record. The parsed record then follows the raw record.
| Output field | Type | Valid Values | Description | Example |
|---|---|---|---|---|
timestamp |
str | ISO 8601 UTC timestamp | The date and time of discovery in UTC | "timestamp"="2024-11-15T16:14:39Z" |
domain |
str | Domain character set restricted by the DNS specification (Letters, Digits, Hyphens) | Apex-level domain for NAD, NOD, and Domain Discovery. The NOH feed returns full hostnames (e.g., including subdomains.). | "domain"="example.com" |
raw_record |
obj | N/A | Contains the raw registry and/or registrar for the domain. | See example below. |
first_request_timestamp |
str | ISO 8601 UTC timestamp | The timestamp of the first request | "first_request_timestamp"="2025-04-23T10:30:17Z" |
requests |
array | N/A | Record request objects | See example below |
data |
str | JSON string | The raw data of the request | "data"="{\"objectClassName\":\"domain\",\"handle\":\"1831890332_DOMAIN_NET-VRSN\"...}" |
source_type |
str | Source type values | The source type of the request | "source_type"="registrar" |
timestamp |
str | ISO 8601 UTC timestamp | The timestamp of the request | "timestamp"="2025-04-23T10:30:18Z" |
url |
str | URL format | The URL associated with the request | "url"="https://rdap.nicproxy.com/domain/domiantools.com" |
parsed_record |
obj | N/A | Contains parsed information from the raw record | See nested fields below |
registrar_request_url |
str | URL format | The URL for the registrar request | "registrar_request_url"="https://rdap.nicproxy.com/domain/domiantools.com" |
registry_request_url |
str | URL format | The URL for the registry request | "registry_request_url"="https://rdap.nicproxy.com/domain/domiantools.com" |
In the following example using domaintools.com, both a registry and registrar record are present (note source_type). The raw records, as well as the content of the parsed record, are removed for brevity.
With the following query:
curl -sH "X-Api-Key: $FEEDAPIKEY" 'https://api.domaintools.com/v1/feed/domainrdap?sessionID=mySOC&top=1'`
The following results are obtained:
{
"timestamp": "2024-11-15T00:00:19Z",
"domain": "domaintools.com",
"raw_record": {
"first_request_timestamp": "2024-11-15T00:00:14Z",
"requests": [
{
"data": "{RAW REGISTRY RECORD}",
"source_type": "registry",
"timestamp": "2024-11-15T00:00:14Z",
"url": "https://rdap.verisign.com/com/v1/domain/domaintools.com"
},
{
"data": "{RAW REGISTRAR RECORD}",
"source_type": "registrar",
"timestamp": "2024-11-15T00:00:16Z",
"url": "https://enom.rdap.tucows.com/domain/DOMAINTOOLS.COM"
}
]
},
"parsed_record": {
"parsed_fields": {PARSED FIELDS},
"registrar_request_url": "https://enom.rdap.tucows.com/domain/DOMAINTOOLS.COM",
"registry_request_url": "https://rdap.verisign.com/com/v1/domain/domaintools.com"
}
}
Download API¶
The download API returns 90 days of historical results in the form of temporary AWS S3 files. The AWS S3 files are signed and come in pairs:
- A data file:
{feed_short_name}/{YYYY-MM-DD}/{feed_short_name}-{YYYYMMDD}.{starthour:HH00}-{endhour:HH00}.json.gz - A checksum file:
{feed_short_name}/{YYYY-MM-DD}/{feed_short_name}-{YYYYMMDD}.{starthour:HH00}-{endhour:HH00}.json.gz.sha256
The API lists the files available for download, after which individual files can be downloaded from the signed URL. The hourly files are gzip-compressed JSON.
Note that setting the limit parameter to an odd number will deliver a data file without its checksum companion.
Download API Base URL¶
Download API Endpoints¶
| Feed | API Feed Endpoint |
|---|---|
| Domain Discovery | domaindiscovery |
| Domain Hotlist | domainhotlist |
| Domain RDAP | domainrdap |
| Domain Risk | domainrisk |
| Newly Active Domains | nad |
| Newly Observed Domains | nod |
| Newly Observed Hostnames | noh |
E.g., api.domaintools.com/v1/download/nad/
Download API Common GET Query Parameters¶
| Parameter | Description | Type | Required? |
|---|---|---|---|
api_key |
API key provided by DomainTools, dashes included | string | Yes (for key auth) |
api_username |
API username provided by DomainTools | string | Yes (for key auth) |
app_name |
Name of your appliance, playbook, module, etc., or in combination. Useful to help with debugging | string | No |
app_partner |
Your product name. Useful to help debugging | string | No |
app_version |
Your version number. Useful to help with debugging | string | No |
limit |
Limit the list of signed files. Ordering of files is always descending, so the latest files are first. | integer | No |
signature |
HMAC hash of your request, using the MD5, SHA1, or SHA256 hashing algorithm |
string | Yes (for HMAC auth) |
timestamp |
Current timestamp for HMAC authentication, in ISO 8601 format. (e.g. 2025-01-10T15:44:39.118Z) | string | Yes (for HMAC auth) |
Download API Query Examples¶
Get the latest, single (limit=1) signed download URL from Newly Observed Domains using curl:
Download API Response Codes¶
| Code | Description |
|---|---|
200 |
OK: The request was successful. |
400 |
Malformed request |
401 |
Unauthorized |
403 |
Forbidden |
422 |
Invalid header query parameter |
If an API call returns a HTTP 206 response, continue submitting the same request (with the same sessionID) until the API returns a HTTP 200, signalling that all the data for the request has been delivered.
Download API Common Response Parameters¶
| Name | Type | Description |
|---|---|---|
download_name |
string | Name of the feed. |
etag |
string | Entity tag (a hash of the object). |
last_modified |
string | Last modified date of the file in ISO 8601 format. |
size |
integer | Size in kilobytes (KB) |
url |
string | Signed AWS CloudFront download URL; consult note below. |
The Download API returns short-lived, signed URLs for two files containing historical feed data that change each hour, where {feed_short_name} is one of: nod, nad, noh, domainrdap, domaindiscovery:
- A data file:
{feed_short_name}/{YYYY-MM-DD}/{feed_short_name}-{YYYYMMDD}.{starthour:HH00}-{endhour:HH00}.json.gz - A checksum file:
{feed_short_name}/{YYYY-MM-DD}/{feed_short_name}-{YYYYMMDD}.{starthour:HH00}-{endhour:HH00}.json.gz.sha256
Note that setting the limit parameter to an odd number will return a checksum file without its data file.
Download API Response Structure and Example¶
API Response¶
Note that returned file URLs are in pairs: a data file (ending in .json.gz) and a checksum file (ending in .json.gz.sha256).
{
"response": {
"download_name": "nod",
"files": [
{
"name": "nod/2025-08-21/nod-20250821.1200-1300.json.gz.sha256",
"last_modified": "2025-08-21T13:00:13+00:00",
"etag": "\"ETAG\"",
"size": "64",
"url": "https://dyyl2mzrdiuqox.cloudfront.net/nod/2025-08-21/nod-20250821.1200-1300.json.gz.sha256?aui=14592&ai=1708207&Expires=1755824426&Signature=SIGNATURE&Key-Pair-Id=KEYPAIRID"
},
{
"name": "nod/2025-08-21/nod-20250821.1200-1300.json.gz",
"last_modified": "2025-08-21T13:00:13+00:00",
"etag": "\"ETAG\"",
"size": "140725",
"url": "https://d2rdimzuqyylox.cloudfront.net/nod/2025-08-21/nod-20250821.1200-1300.json.gz?aui=14592&ai=1708207&Expires=1755824426&Signature=SIGNATURE&Key-Pair-Id=KEYPAIRID"
}
]
}
}
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, uncompressed to a JSON file containing the same information as the Feed API.
S3 Delivery¶
As an alternative to the Download API, DomainTools can deliver feed data directly to your Amazon S3 bucket. This cloud-based delivery method replaces the legacy transfer server system and supports scheduled data pushes at custom intervals (such as every 5 minutes or daily).
Requirements:
- An Amazon S3 bucket with write access
- S3 credentials (access key and secret key)
- Coordination with DomainTools to configure the delivery schedule and feed selection
How It Works
DomainTools configures an automated sync process that transfers feed files from DomainTools' S3 infrastructure to your designated S3 bucket. The sync runs on your specified schedule, ensuring you receive feed data without polling the Download API.
Setup
To enable S3 delivery, contact enterprisesupport@domaintools.com with:
- Your S3 bucket name and region
- The feed(s) you want delivered
- Your preferred delivery schedule
- S3 credentials for write access (provided securely during setup)
DomainTools manages the sync schedule and monitors for delivery failures.
Response Policy Zone (RPZ)¶
RPZ delivery is available for Newly Active Domains (nad) and Newly Observed Domains (nod).
Hotlists are delivered over DNS Zone Transfer from DomainTools RPZ providers using AXFR, IXFR, and DNS Notify.
The DNS resolver using our RPZ feed will respond with an NXDOMAIN (“no such domain”) status code for queries for matching domains in the Threat Feed.
RPZ Access Configuration¶
RPZ Zone Names¶
Zone name labels are constructed (left to right) from a time period, followed by a list name, followed by .rpz.domaintools.com:
Available time intervals: 10m, 30m, 1h, 3h, 12h.
For example, the 1 hour NOD list: 1h.nod.rpz.domaintools.com.
RPZ Provider Allowlist¶
Before attempting to connect to our RPZ provider, please be sure to provide two sets of IP addresses to DomainTools at enterprisesupport@domaintools.com:
- The IP address(es) from which you will connect to the RPZ provider server;
- The IP address(es) to which you would like DNS Notify messages to be sent.
These two sets of addresses are typically the same.
You will also need to add rules to your firewall’s access control list(s) for DomainTools hosts to send UDP packets to port 53 of your DNS server, so that it can receive the DNS NOTIFY packets for updates.
RPZ Provider Server Addresses¶
Primary Server:
IPv4: 104.244.14.88
Fallback Server:
IPv4: 104.244.14.89
RPZ TSIG Information¶
- TSIG key: Provided by enterprisesupport@domaintools.com
- TSIG key algorithm: hmac-sha512
- TSIG key name: Provided by enterprisesupport@domaintools.com
Recommendation: Local RPZ Allowlist Zone¶
We recommend that customers maintain an allowlist zone for instances when a customer has more, specific information about a domain than DomainTools. Contact enterprisesupport@domaintools.com until this recommendation is fully documented in Q1 2025.
RPZ Response Format¶
Each hotlist is formatted in accordance with the draft specification for DNS Response Policy Zones. All domain entries are listed with NXDOMAIN outcomes by default (CNAME .). Each domain entry contains both apex and wildcard *. entries (i.e., two records per domain).
For example:
RPZ Troubleshooting¶
The DNS resolver using our RPZ feed will respond with an NXDOMAIN (“no such domain”) status code for queries for matching domains in the RPZ feed. The NXDOMAIN response will include an SOA record in the ADDITIONAL section of the DNS response (and no ANSWER). This SOA record may be used to troubleshoot the RPZ feed. In addition, see your RPZ related debugging logs for your DNS resolver.
This SOA will identify that it came from the RPZ. For example, the following label tells you what RPZ feed was used and the SOA RNAME indicates the primary DNS server (rpz-ns1.domaintools.com) that hosts this RPZ zone:
;; ADDITIONAL SECTION:
3h.nod.rpz.domaintools.com. 86400 IN SOA rpz-ns1.domaintools.com. noc.domaintools.com. 36625313 600 300 86400 86400
Our RPZ Threat Feeds also have a testing domain entry and its corresponding wildcard which may be used to verify the RPZ feed is loaded and working. You may do a DNS lookup, like with dig, for test.rpz.domaintools.test and it should respond with the NXDOMAIN and the ADDITIONAL section SOA record indicating its originating RPZ feed. If the ADDITIONAL section SOA record response does not have the domainhotlist feed name, then it did not come from the RPZ.
Python Wrapper Methods¶
Consult our GitHub documentation at https://github.com/DomainTools/python_api.
Last modified: Oct 7, 2025