DomainIQ
Python client for the DomainIQ API — Domain Intelligence and Security Research
Overview
DomainIQ is a modern Python client for the DomainIQ API, providing comprehensive domain intelligence and security research capabilities. It supports both synchronous and asynchronous operations, making it ideal for threat intelligence analysts, security researchers, and incident responders.
Key Features
| Feature | Description |
|---|---|
| Sync & Async Clients | Full synchronous and asynchronous API support |
| Structured Models | Dataclass-based response models for clean API responses |
| Flexible Config | Multiple API key sources (env, file, parameter; CLI prompt when needed) |
| CLI Tool | Comprehensive command-line interface included |
| Error Handling | Custom exception hierarchy for robust error handling |
| Type Hints | Full type annotations throughout the codebase |
| Retry Logic | Exponential backoff with configurable retry settings |
| Context Managers | Automatic resource cleanup with with / async with |
API Coverage
Lookups WHOIS, DNS, Categorization, Snapshots, Reverse DNS
Reports Domain, Name, Organization, Email, IP
Search Domain Search, Reverse Search (Email/Name/Org/IP/MX)
Bulk Bulk DNS, Bulk WHOIS, Bulk Domain IP
Monitoring Create/List/Delete Reports, Typosquatting, Change Tracking
Installation
From PyPI (Recommended)
pip install domainiq
With Async Support
pip install domainiq[async]
From Source
git clone https://github.com/seifreed/DomainIQ.git
cd DomainIQ
python3 -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate
pip install -e .
Quick Start
API Key Configuration
The library supports multiple ways to provide your DomainIQ API key:
# Environment variable (recommended)
export DOMAINIQ_API_KEY="your_api_key_here"
# Configuration file
echo "your_api_key_here" > ~/.domainiq
Or pass it directly in code:
from domainiq import DomainIQClient
client = DomainIQClient(api_key="your_api_key_here")
Basic Usage
from domainiq import DomainIQClient
from domainiq.models import DNSRecordType
# Create client (API key loaded automatically)
client = DomainIQClient()
# WHOIS lookup
whois = client.whois_lookup(domain="example.com")
if whois:
print(f"Registrar: {whois.registrar}")
print(f"Created: {whois.creation_date}")
# DNS lookup
dns = client.dns_lookup("example.com", record_types=[DNSRecordType.A, DNSRecordType.MX])
if dns:
for record in dns.records:
print(f"{record.type}: {record.value}")
client.close()
Async Usage
import asyncio
from domainiq.async_client import AsyncDomainIQClient
async def main():
async with AsyncDomainIQClient() as client:
domains = ["example.com", "google.com", "github.com"]
results = await client.concurrent_whois_lookup(
targets=domains, max_concurrent=5
)
for domain, result in zip(domains, results):
if result:
print(f"{domain}: {result.registrar}")
asyncio.run(main())
Usage
Command Line Interface
| Option | Description |
|---|---|
--whois-lookup |
WHOIS lookup for a domain |
--dns-lookup |
DNS record query |
--domain-report |
Comprehensive domain report |
--bulk-dns |
Bulk DNS lookups |
--bulk-whois |
Bulk WHOIS lookups |
--domain-search |
Search domains by keywords |
--reverse-search-type |
Reverse search (email/name/org) |
--monitor-list |
List active monitors |
--create-monitor-report |
Create a new monitor |
--email-report |
Report for an email address |
--ip-report |
Report for an IP address |
# Basic usage
domainiq --whois-lookup example.com
domainiq --dns-lookup example.com --types A,MX
domainiq --domain-report example.com
# Bulk operations
domainiq --bulk-dns example.com google.com github.com
domainiq --bulk-whois example.com google.com
# Monitoring
domainiq --monitor-list
domainiq --create-monitor-report keyword "My Monitor" --email-alert
Python Library
Public API Surface
Since 3.0.0, the package root exports clients, exceptions, model types, and
protocol contracts. Response parser helpers are intentionally not re-exported
from domainiq; endpoint methods own response parsing internally.
Context Manager
with DomainIQClient() as client:
whois = client.whois_lookup(domain="example.com")
dns = client.dns_lookup("example.com")
# Client is automatically closed
Error Handling
from domainiq import (
DomainIQError, # Base exception
DomainIQAPIError, # API-related errors
DomainIQAuthenticationError, # Invalid API key
DomainIQRateLimitError, # Rate limiting
DomainIQTimeoutError, # Request timeouts
DomainIQConfigurationError, # Configuration issues
)
try:
result = client.whois_lookup("example.com")
except DomainIQAuthenticationError:
print("Invalid API key")
except DomainIQRateLimitError as e:
print(f"Rate limited. Retry after: {e.retry_after} seconds")
except DomainIQTimeoutError:
print("Request timed out")
except DomainIQAPIError as e:
print(f"API error: {e}")
Custom Configuration
from domainiq import DomainIQClient
from domainiq.config import Config
config = Config(
api_key="your_key",
base_url="https://api.domainiq.com/custom",
timeout=60,
max_retries=5,
retry_delay=2,
)
client = DomainIQClient(config=config)
Data Models
# WhoisResult
whois = client.whois_lookup("example.com")
whois.domain # str
whois.registrar # str
whois.creation_date # datetime
whois.expiration_date # datetime
whois.registrant_name # str
whois.nameservers # List[str]
# DNSResult
dns = client.dns_lookup("example.com")
dns.domain # str
for record in dns.records:
record.type # str (A, MX, CNAME, etc.)
record.value # str
record.ttl # int
# DomainReport
report = client.domain_report("example.com")
report.domain # str
report.risk_score # float
report.categories # List[str]
report.related_domains # List[str]
Examples
Security Research Workflow
from domainiq import DomainIQClient
from datetime import datetime
client = DomainIQClient()
suspicious_domains = ["suspicious-site.com", "fake-bank.net"]
for domain in suspicious_domains:
whois = client.whois_lookup(domain=domain)
if whois and whois.creation_date:
days_old = (datetime.now() - whois.creation_date.replace(tzinfo=None)).days
if days_old < 30:
print(f"{domain} is newly registered ({days_old} days old)")
categories = client.domain_categorize([domain])
if categories and categories[0].categories:
for cat in categories[0].categories:
if any(risk in cat.lower() for risk in ['malware', 'phishing', 'suspicious']):
print(f"{domain} categorized as: {cat}")
Process Multiple Domains
from domainiq import DomainIQClient
from pathlib import Path
client = DomainIQClient()
domains = Path("domains.txt").read_text().splitlines()
for domain in domains:
whois = client.whois_lookup(domain=domain.strip())
if whois:
print(f"{domain}: {whois.registrar}")
More examples in the examples/ directory:
basic_usage.py— Fundamental operationsasync_usage.py— High-performance async operationssecurity_research.py— Security analysis workflows
Requirements
- Python 3.13+
- See pyproject.toml for full dependency list
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
Support the Project
If you find DomainIQ useful, consider supporting its development:
License
This project is licensed under the MIT License - see the LICENSE.md file for details.
Attribution Required:
- Author: Marc Rivero | @seifreed
- Repository: github.com/seifreed/DomainIQ
Made with dedication for the threat intelligence community
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file domainiq_cli-3.1.0.tar.gz.
File metadata
- Download URL: domainiq_cli-3.1.0.tar.gz
- Upload date:
- Size: 108.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
32e6a9f5c5bc4216f6840a60e1aa2070a0f77ac3159c5e1219909469bc7a0737
|
|
| MD5 |
f01a39d9a878f7dade166f371fcacdd4
|
|
| BLAKE2b-256 |
6360ccfdfaf6d7b5d88bcca4b17876615cffd093ad3794024177aa0a90559109
|
Provenance
The following attestation bundles were made for domainiq_cli-3.1.0.tar.gz:
Publisher:
release.yml on seifreed/DomainIQ
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
domainiq_cli-3.1.0.tar.gz -
Subject digest:
32e6a9f5c5bc4216f6840a60e1aa2070a0f77ac3159c5e1219909469bc7a0737 - Sigstore transparency entry: 2499481481
- Sigstore integration time:
-
Permalink:
seifreed/DomainIQ@fb783908369f4136a7a13cde83fdd6ea42dd44ca -
Branch / Tag:
refs/tags/v3.1.0 - Owner: https://github.com/seifreed
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@fb783908369f4136a7a13cde83fdd6ea42dd44ca -
Trigger Event:
push
-
Statement type:
File details
Details for the file domainiq_cli-3.1.0-py3-none-any.whl.
File metadata
- Download URL: domainiq_cli-3.1.0-py3-none-any.whl
- Upload date:
- Size: 87.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d69d73ef9782d3cd01dcfe6f46f8f6bb1f1344e63133a2efaa12454b01fc35ed
|
|
| MD5 |
b38f36f1a6fb563b26ea46d4d00d8408
|
|
| BLAKE2b-256 |
a1ceb30e55a3cd8121722ff35348e3026b04c1f4a489ed5b27a063c104fcd124
|
Provenance
The following attestation bundles were made for domainiq_cli-3.1.0-py3-none-any.whl:
Publisher:
release.yml on seifreed/DomainIQ
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
domainiq_cli-3.1.0-py3-none-any.whl -
Subject digest:
d69d73ef9782d3cd01dcfe6f46f8f6bb1f1344e63133a2efaa12454b01fc35ed - Sigstore transparency entry: 2499481483
- Sigstore integration time:
-
Permalink:
seifreed/DomainIQ@fb783908369f4136a7a13cde83fdd6ea42dd44ca -
Branch / Tag:
refs/tags/v3.1.0 - Owner: https://github.com/seifreed
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@fb783908369f4136a7a13cde83fdd6ea42dd44ca -
Trigger Event:
push
-
Statement type: