Python SDK¶
The official Python SDK provides a unified interface to DomainTools APIs, including Iris Investigate, Iris Enrich, Iris Detect, Lookup & Monitor APIs, and Threat Feeds.
Installation¶
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
Quick start¶
Create an API instance with your credentials:
Call any API endpoint as a method:
# 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
import json
api = API('your_username', 'your_api_key')
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
Authentication¶
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.
HMAC authentication (default)¶
from domaintools import API
# HMAC is used automatically for most endpoints
api = API('your_username', 'your_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)¶
Threat Feeds automatically switch to header authentication - you use the same initialization:
# Same initialization works for feeds
api = API('your_username', 'your_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.
Storing credentials¶
Store credentials securely using environment variables:
import os
from domaintools import API
username = os.environ.get('DOMAINTOOLS_USERNAME')
api_key = os.environ.get('DOMAINTOOLS_API_KEY')
api = API(username, api_key)
Create ~/.dtapi with your credentials on separate lines:
Key features¶
- Comprehensive API support - Access Iris, Threat Feeds, and Lookup & Monitor 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
Product overview¶
- Iris Investigate - Deep domain analysis and infrastructure mapping
- Iris Enrich - High-volume domain enrichment for SIEM/SOAR
- Iris Detect - Automated lookalike domain discovery
- Threat Feeds - Real-time threat intelligence feeds
- Lookups - Historical domain intelligence
- Monitors - Automated alerting on changes
Working with responses¶
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!")
Error handling¶
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")
Getting help¶
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())
Next steps¶
- Iris Platform - Learn about Iris Investigate, Enrich, and Detect
- Threat Feeds - Access real-time threat intelligence
- Lookups & Monitors - Historical data and automated alerts
- Advanced Features - Async, CLI, workflows, and pagination
- Configuration - Rate limits, proxies, SSL, and more
- Examples - Code examples and common patterns
Additional resources¶
- GitHub Repository - Source code, examples, and issue tracking
- PyPI Package - Latest releases and version history
- API Reference - Complete API endpoint documentation
- Python Version Support - Supported Python versions