What Information Does a Holehe Module Return? A Complete Field Reference
Each Holehe module returns a standardized result dictionary with nine fields including service name, domain, rate-limiting status, and whether an email address exists on the platform.
Holehe, the open-source OSINT tool by megadose/holehe, checks email address registration status across hundreds of online services. Understanding what information a Holehe module returns is essential for building reliable scripts and interpreting results correctly. This article breaks down the exact schema used by every module in the codebase.
The Standard Result Dictionary Schema
Every module in holehe/modules/ constructs and appends an identical dictionary structure to the shared out list. This uniformity allows holehe.core to aggregate results without service-specific parsing.
The nine fields returned by any Holehe module are:
| Field | Type | Purpose |
|---|---|---|
| name | string | Human-readable service name (e.g., Twitter, GitHub) |
| domain | string | Primary service domain (e.g., twitter.com, github.com) |
| method | string | Interaction type; always "register" as modules probe registration endpoints |
| frequent_rate_limit | boolean | True if the service aggressively rate-limits; alerts callers to throttle |
| rateLimit | boolean | True if the current request triggered rate-limiting or throttling |
| exists | boolean | True when the email is detected as already registered on the service |
| emailrecovery | null/string | Placeholder for recovery email extraction (currently always None) |
| phoneNumber | null/string | Placeholder for disclosed phone numbers (currently always None) |
| others | null/dict | Generic extension field for additional data (currently always None) |
How Modules Build the Result Dictionary
In holehe/modules/social_media/twitter.py and similar module files, the pattern follows this exact structure:
out.append({
"name": name,
"domain": domain,
"method": method,
"frequent_rate_limit": frequent_rate_limit,
"rateLimit": False,
"exists": True,
"emailrecovery": None,
"phoneNumber": None,
"others": None,
})
The out parameter passed to each module function is a list that accumulates these dictionaries. holehe.core later processes this list to generate CLI tables, JSON output, or other formats.
Working with Holehe Module Output Programmatically
Direct Module Invocation
For targeted checks against a single service, import and call the module directly:
import asyncio
from aiohttp import ClientSession
from holehe.modules.social_media.twitter import twitter
async def check_twitter(email: str):
async with ClientSession() as client:
results = []
await twitter(email, client, results)
return results[0] # Returns the standard dictionary
# Execute
info = asyncio.run(check_twitter("example@example.com"))
print(info["exists"]) # True if registered, False if available
print(info["rateLimit"]) # Check if request was throttled
Processing Multiple Results
Filter successful hits by examining the exists field:
import asyncio
from aiohttp import ClientSession
from holehe.core import run_all_checks
async def find_existing_accounts(email: str):
async with ClientSession() as client:
all_results = await run_all_checks(email, client)
# Filter to services where email is already registered
registered = [r for r in all_results if r["exists"]]
return registered
# Returns list of dictionaries for active accounts
accounts = asyncio.run(find_existing_accounts("target@example.com"))
for acc in accounts:
print(f"{acc['name']}: {acc['domain']}")
Rate-Limit Handling Strategies
The dual rate-limiting fields enable intelligent request management:
def should_retry(result: dict) -> bool:
"""Determine if a retry makes sense for this result."""
if result["rateLimit"]:
return True # Hit limit—retry after delay
if result["frequent_rate_limit"]:
return False # Service aggressively limits—skip
return False
def priority_score(result: dict) -> int:
"""Score services by reliability for batch processing."""
score = 0
if not result["frequent_rate_limit"]:
score += 2 # Prefer stable services
if not result["rateLimit"]:
score += 1 # Prefer non-throttled
return score
CLI Output Format
When using the command-line interface, the same dictionary structure appears in JSON output:
pip install holehe
holehe -e example@example.com --json
Sample structured output:
[
{
"name": "Twitter",
"domain": "twitter.com",
"method": "register",
"frequent_rate_limit": false,
"rateLimit": false,
"exists": true,
"emailrecovery": null,
"phoneNumber": null,
"others": null
}
]
Key Source Files
Understanding what information a Holehe module returns requires examining these core files:
holehe/modules/social_media/twitter.py— Exemplary module showing registration endpoint probing and result constructionholehe/modules/social_media/facebook.py— Demonstrates rate-limit detection andfrequent_rate_limitflag usageholehe/core.py— Orchestrates module loading, executes checks, and aggregates theoutlist into final output
Summary
- Every Holehe module returns an identical nine-field dictionary to ensure consistent parsing across all services
- The
existsboolean is the primary indicator of whether an email is registered on a given platform - Rate-limiting is tracked via two fields:
frequent_rate_limitfor known aggressive services,rateLimitfor the current request status - Placeholder fields (
emailrecovery,phoneNumber,others) reserve schema space for future data extraction capabilities - The
outlist pattern enables both individual module testing and bulk processing throughholehe.core
Frequently Asked Questions
Why does every Holehe module use the same return structure?
Uniform dictionary schemas enable reliable scripting without service-specific parsing logic. As implemented in megadose/holehe, this design lets holehe.core aggregate results from hundreds of modules without knowing individual service details in advance.
What does the method field indicate when it is always "register"?
The method field currently reflects that all modules probe registration endpoints to infer account existence. This value is preserved for forward compatibility—future modules might use different interaction types, and callers can filter or route behavior accordingly.
How should I handle services marked with frequent_rate_limit: True?
Treat these services as high-risk for batch processing. The flag indicates aggressive rate-limiting policies. Implement exponential backoff, reduce concurrency, or deprioritize these modules when checking large email lists to avoid IP blocks.
Can emailrecovery or phoneNumber ever contain actual data?
Currently no modules in the repository populate these fields—they exist as schema placeholders for future extraction capabilities. Your code should handle None values defensively while remaining compatible if future versions add data to these fields.
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 →