Standard Output Format for Holehe Modules: Complete Developer Guide
Each Holehe module appends a standardized dictionary with nine specific keys—name, domain, method, frequent_rate_limit, rateLimit, exists, emailrecovery, phoneNumber, and others—to a shared out list, enabling uniform result aggregation across all OSINT checks.
Holehe is an asynchronous email reconnaissance tool developed by megadose that verifies account existence across hundreds of platforms. Understanding the standard output format for Holehe modules is critical for developers extending the framework or parsing results programmatically. This guide examines the exact schema enforced by the core engine and demonstrates implementation patterns using production code from the repository.
The Standardized Dictionary Schema
Every module must conform to a strict dictionary contract when appending results. According to the launch_module implementation in holehe/core.py (lines 66-71), the core engine expects dictionaries containing these exact keys:
name— The service identifier (e.g.,"twitter","facebook").domain— The primary domain of the service (e.g.,"twitter.com").method— The interaction type, typically"register"for registration checks.frequent_rate_limit— Boolean flag indicating whether the service enforces aggressive rate limiting.rateLimit— Boolean set toTruewhen the request hits a rate limit, otherwiseFalse.exists— Boolean indicating whether the email is registered on the service.emailrecovery— Optional string containing a recovery email hint, orNone.phoneNumber— Optional string containing an associated phone number, orNone.others— Dictionary for additional metadata (e.g., full name, account creation date), orNone.
This schema ensures that the aggregation logic in print_result and export_csv functions can process outputs from any module without service-specific parsing.
Core Module Execution Logic
The holehe/core.py file orchestrates module discovery and execution. The import_submodules function (lines 36-47) dynamically loads every Python file placed in holehe/modules/, while launch_module invokes each check asynchronously.
The out parameter is a Python list passed by reference to all concurrent modules. Because Holehe uses asyncio to run checks in parallel, the shared list accumulates standardized dictionaries from hundreds of sources simultaneously. The core engine then iterates over this list to generate CLI tables or CSV exports, relying entirely on the consistent key structure described above.
Reference Implementations from Production Modules
Twitter Module Pattern
The twitter.py module (lines 17-31) provides a minimal yet complete implementation. After querying Twitter's registration endpoint, it constructs the dictionary with all required keys, setting exists based on the HTTP response status and rateLimit to False unless the request encounters throttling.
Facebook Module Complexity
The facebook.py module (lines 30-82) demonstrates advanced usage involving CSRF token extraction and session management. Despite the complex authentication flow, it maintains the identical output structure, proving that the standard format accommodates varied API interaction patterns while preserving consistency for the core aggregator.
Creating Custom Modules
To build a compatible module, define an asynchronous function accepting three parameters: email, client (an HTTPX AsyncClient), and out (the shared results list).
# mycustomservice.py
import httpx
async def mycustomservice(email, client, out):
name = "mycustomservice"
domain = "example.com"
method = "register"
frequent_rate_limit = False
try:
response = await client.get(
f"https://{domain}/api/check",
params={"email": email},
timeout=10
)
exists = response.json().get("registered", False)
out.append({
"name": name,
"domain": domain,
"method": method,
"frequent_rate_limit": frequent_rate_limit,
"rateLimit": False,
"exists": exists,
"emailrecovery": None,
"phoneNumber": None,
"others": None
})
except httpx.HTTPStatusError:
out.append({
"name": name,
"domain": domain,
"method": method,
"frequent_rate_limit": frequent_rate_limit,
"rateLimit": True,
"exists": False,
"emailrecovery": None,
"phoneNumber": None,
"others": None
})
Place this file in holehe/modules/social_media/ to enable automatic discovery by the import_submodules loader.
Command-Line and Programmatic Usage
Invoke Holehe via CLI to observe the standardized output:
holehe target@example.com
For programmatic integration, import the core launcher directly:
import asyncio
import httpx
from holehe.core import launch_module
from holehe.modules.social_media import twitter
async def check_single():
async with httpx.AsyncClient() as client:
results = []
await launch_module(twitter.twitter, "user@example.com", client, results)
for entry in results:
if entry["exists"]:
print(f"Found on {entry['name']}: {entry['domain']}")
asyncio.run(check_single())
The results list contains dictionaries adhering strictly to the nine-key schema, regardless of which modules executed.
Summary
- The standard output format for Holehe modules requires a dictionary with exactly nine keys:
name,domain,method,frequent_rate_limit,rateLimit,exists,emailrecovery,phoneNumber, andothers. - Modules append these dictionaries to a shared
outlist passed by thelaunch_modulefunction in holehe/core.py. - The
existsboolean indicates account presence, whilerateLimitsignals throttling issues, andothersaccommodates supplementary metadata. - Production examples in twitter.py and facebook.py demonstrate both simple and complex implementations of the schema.
- Custom modules must use the async signature
(email, client, out)and maintain the exact key structure for compatibility with the core aggregation engine.
Frequently Asked Questions
What happens if a module omits required keys from the output dictionary?
The core engine's formatting functions in holehe/core.py expect all nine keys to be present. Omitting keys such as exists or rateLimit will raise a KeyError during result processing or CSV export. Always populate every field, using None for optional data and False for boolean defaults when information is unavailable.
Can modules add custom fields outside the standard schema?
While the others key exists specifically for extensible metadata, adding new top-level keys outside the defined schema breaks compatibility with the core aggregation logic. Store any additional data—such as profile URLs or account creation dates—within the others dictionary to maintain forward compatibility with future Holehe versions.
How does the output format handle partial or rate-limited responses?
When a module encounters rate limiting, it must set rateLimit to True and exists to False. The frequent_rate_limit metadata flag alerts users that the service aggressively restricts requests, allowing the CLI to implement delays or warning messages. This standardized error handling ensures consistent behavior across all 300+ supported platforms.
Is the dictionary format consistent between CLI usage and Python API calls?
Yes. Whether invoking Holehe from the terminal, importing launch_module directly, or integrating the modules into larger async workflows, the standard output format remains identical. The dictionary structure serves as the universal contract between individual service modules and the core processing engine, ensuring predictable data structures regardless of the interface used.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →