Skip to content

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

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

Quick start

Create an API instance with your credentials:

from domaintools import API

api = API('your_username', 'your_api_key')

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:

API_USERNAME
API_KEY

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

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

Additional resources