Skip to content

DomainTools Python SDK

The official DomainTools Python SDK provides a unified interface to DomainTools APIs. This includes Iris Investigate, Iris Enrich, Iris Detect, Lookups and Monitors APIs, and Threat Feeds.

pip install domaintools_api --upgrade

It is usually best practice to install in a virtual environment:

python3 -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
pip install domaintools_api --upgrade

Read credentials from environment variables and create an API instance:

import os
from domaintools import API
api = API(os.environ["DOMAINTOOLS_USERNAME"], os.environ["DOMAINTOOLS_API_KEY"])

Set the variables in your shell before running:

export DOMAINTOOLS_USERNAME=your_username
export DOMAINTOOLS_API_KEY=your_api_key

Call any API endpoint as a method:

import os
import json
from domaintools import API
api = API(os.environ["DOMAINTOOLS_USERNAME"], os.environ["DOMAINTOOLS_API_KEY"])
# Iris Enrich - batch domain enrichment
results = api.iris_enrich('domaintools.com')
print(results.response())
# Iris Investigate - search and pivot
results = api.iris_investigate('example.com')
for domain in results:
print(f"{domain['domain']}: Risk {domain['domain_risk']['risk_score']}")
# Domain Profile - comprehensive lookup
profile = api.domain_profile('google.com')
print(profile.response()['registrant']['name'])
# Threat Feeds - real-time intelligence
feed = api.nod(after=-3600) # Last hour
for json_string in feed.response():
record = json.loads(json_string)
print(f"New domain: {record['domain']}")
break

See Authentication for the full credential reference across DomainTools products. This section covers SDK-specific behavior.

The SDK uses HMAC-signed authentication by default for most endpoints, which is the most secure method. The API key is never sent in the request - instead, it’s used to create a cryptographic signature.

Important: Threat Feeds automatically use header-based authentication - the SDK handles this transparently, so you don’t need to configure anything special.

import os
from domaintools import API
# HMAC is used automatically for most endpoints
api = API(os.environ["DOMAINTOOLS_USERNAME"], os.environ["DOMAINTOOLS_API_KEY"])
# Works for Iris, Lookups, Monitors, etc.
result = api.domain_profile('domaintools.com')
result = api.iris_investigate(domain='example.com')

Header authentication (automatic for feeds)

Section titled “Header authentication (automatic for feeds)”

Threat Feeds automatically switch to header authentication - you use the same initialization:

import os
from domaintools import API
# Same initialization works for feeds
api = API(os.environ["DOMAINTOOLS_USERNAME"], os.environ["DOMAINTOOLS_API_KEY"])
# SDK automatically uses header auth for feeds
result = api.nod(after=-3600)
result = api.nad(sessionID='my-session')

Note: The SDK detects feed endpoints and switches authentication methods automatically. You don’t need to set header_authentication=True for feeds.

For storage and rotation guidance — including the trade-offs of env vars, OS keychains, and secret managers — see Storing credentials securely.

You can also use the ~/.dtapi file. Create it with your credentials on separate lines:

API_USERNAME
API_KEY
  • Comprehensive API support - Access Iris, Threat Feeds, and Lookups and Monitors APIs through a unified interface
  • CLI tool included - Command-line interface for quick queries and scripting
  • Async support - Built-in asynchronous operations for high-performance applications
  • Type hints - Full Python type annotations for better IDE support
  • Flexible authentication - Support for HMAC, header, and open-key authentication
  • Real-time feeds - Specialized support for streaming threat feed data
  • Rate limiting - Automatic rate limit management based on your account
  • Error handling - Specific exceptions for different error conditions

Access response data using dictionary-like syntax:

# Get the full response structure
profile = api.domain_profile('google.com')
data = profile.data() # Returns {'response': {...}}
# Get just the response content
response = profile.response() # Returns {...}
# Access specific fields
title = profile['website_data']['title']
# Check status
if profile.status == 200:
print("Success!")

The SDK raises specific exceptions for different error conditions:

from domaintools.exceptions import (
BadRequestException,
NotAuthorizedException,
ServiceUnavailableException
)
try:
result = api.domain_profile('example.com')
except BadRequestException as e:
print(f"Bad request: {e.reason['error']['message']}")
except NotAuthorizedException:
print("Authentication failed")
except ServiceUnavailableException:
print("Service unavailable or rate limit exceeded")

Use Python’s built-in help to explore available endpoints:

# See all available methods
help(api)
# Get details on a specific endpoint
help(api.iris_investigate)
# List available API calls for your account
print(api.available_api_calls())