Holehe Standard Module Output Format: Schema and Structure Explained
Holehe modules return a standardized ten-field dictionary containing keys such as exists, rateLimit, emailrecovery, and domain, enabling the core engine in holehe/core.py to aggregate and display results uniformly across all services.
Holehe is an open-source email investigation framework developed by megadose that asynchronously queries over 120 websites to determine if an email address is registered. According to the megadose/holehe source code, every service-specific module adheres to a strict standard module output format that returns a predictable dictionary schema. This unified structure allows the CLI and downstream automation tools to process results from any module without custom parsing logic.
Standard Output Schema Definition
Each module must return a dictionary containing the following ten standardized fields as documented in the README and enforced by print_result in holehe/core.py (lines 22‑48):
- name (
str): Internal module identifier (e.g.,snapchat). - domain (
str): Primary domain of the service (e.g.,snapchat.com). - method (
str): The authentication vector checked (login,register,password recovery, etc.). - frequent_rate_limit (
bool): Flag indicating if the service commonly imposes rate limits. - rateLimit (
bool):Trueif the current request was rate-limited, otherwiseFalse. - exists (
bool):Trueif an account exists for the supplied email on the target service. - emailrecovery (
str | None): Partially obfuscated recovery email address, if revealed by the service. - phoneNumber (
str | None): Partially obfuscated recovery phone number, if available. - others (
dict | None): Additional metadata such as full name or account creation date. - error (
bool, optional): Present only when an unexpected exception occurs during execution.
How the Core Engine Processes Module Output
The architectural flow that enforces this schema operates in three stages within the megadose/holehe codebase.
Module Execution Stage: Individual modules (e.g., holehe.modules.social_media.snapchat) perform asynchronous HTTP requests using httpx, parse the response, and construct a dictionary matching the exact schema above. In holehe/modules/social_media/snapchat.py (lines 31‑38), the module explicitly assigns values to each required key before returning.
Aggregation Stage: The core runner (launch_module in holehe/core.py) catches any exceptions during module execution. If an error occurs, it injects an "error": True entry into the output and populates default values for the remaining fields to maintain schema consistency.
Presentation Stage: All module dictionaries are collected into a list named out, sorted, and passed to print_result. This function interprets the standardized fields—specifically rateLimit, exists, and others—to generate the colored CLI output, ensuring uniform formatting regardless of which service was queried.
Implementing the Format in Module Code
Service modules instantiate the standard dictionary directly in their return statements. The following pattern from snapchat.py demonstrates the implementation:
# From holehe/modules/social_media/snapchat.py (lines 31-38)
return {
"name": "snapchat",
"domain": "snapchat.com",
"method": "register",
"frequent_rate_limit": False,
"rateLimit": False,
"exists": True,
"emailrecovery": None,
"phoneNumber": None,
"others": {}
}
This explicit construction ensures that print_result in holehe/core.py receives data in the expected structure, allowing the CLI to render results without additional transformation logic.
Working with Module Output Programmatically
You can interact with the standard module output format directly through Python to build custom workflows or integrate Holehe into larger applications.
Invoking a Single Module Directly
To retrieve the standardized dictionary from an individual module without running the full CLI:
import httpx
import trio
from holehe.modules.social_media.snapchat import snapchat
async def check_single_email():
email = "test@example.com"
out = []
async with httpx.AsyncClient() as client:
await snapchat(email, client, out)
print(out)
# Output: [{'name': 'snapchat', 'domain': 'snapchat.com', 'method': 'register', ...}]
trio.run(check_single_email)
Running the Full Engine Programmatically
To execute the complete workflow and receive all module outputs:
import trio
from holehe.core import maincore
async def run_full_scan():
# maincore parses arguments, launches all modules, and prints results
await maincore()
trio.run(run_full_scan)
maincore collects every module’s standardized dictionary, sorts the resulting list, and feeds it to print_result for terminal display.
Parsing Results for Automation
Because every entry follows the identical schema, you can safely filter the output list:
def extract_existing_accounts(results):
"""Filter the standardized output for confirmed accounts."""
return [r for r in results if r.get("exists") is True]
# Example usage with collected results
existing = extract_existing_accounts(out)
for account in existing:
recovery = account.get("emailrecovery") or account.get("phoneNumber")
print(f"{account['domain']}: {recovery}")
Summary
- Holehe modules return a standardized dictionary with ten specific keys including
exists,rateLimit, anddomain. - The schema is enforced by
print_resultinholehe/core.pyand implemented consistently across all modules such assnapchat.py. - The
launch_modulefunction in the core engine handles exceptions by injecting an"error"flag while preserving the standard structure. - This unified format allows the CLI and external scripts to process results from over 120 services without custom parsers.
Frequently Asked Questions
What fields are required in every Holehe module output dictionary?
Every module must return a dictionary containing name, domain, method, frequent_rate_limit, rateLimit, exists, emailrecovery, phoneNumber, and others. The error field is optional and only included when an exception occurs. These requirements are documented in the README and enforced by the core printing logic in holehe/core.py.
How does Holehe indicate rate limiting in the standard output?
Modules set the rateLimit boolean to True when the service rejects the request due to throttling. Additionally, modules declare frequent_rate_limit as True during initialization if the service is known for aggressive rate limiting, allowing the CLI to set appropriate user expectations.
Can I access Holehe module results without using the command-line interface?
Yes. You can import individual modules (e.g., from holehe.modules.social_media.snapchat import snapchat) and call them with an httpx.AsyncClient and an output list. The module appends the standardized dictionary to your list, which you can then process programmatically without invoking maincore or the CLI.
What happens when a module fails to complete its check?
If a module raises an unexpected exception, the launch_module function in holehe/core.py catches the error and returns a dictionary with the error key set to True. The remaining fields are populated with default values to maintain schema consistency, ensuring that print_result can still process the entry without crashing.
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 →