Holehe Module Result Dictionary: Complete Schema and Usage Guide
Every Holehe module returns a standard Python dictionary with six fixed keys: name, rateLimit, exists, emailrecovery, phoneNumber, and others.
The Holehe osint (Open Source Intelligence) tool, developed by megadose, uses a consistent result format across all 120+ modules to report whether an email address is registered on various online services. This article explains the Holehe module result dictionary schema, shows how to access each field programmatically, and provides working code examples from the actual source code.
What Is the Holehe Module Result Dictionary
When you run Holehe—either from the command line or as a Python library—each service check produces a single dictionary. Every module in holehe/modules/ follows this exact pattern, making it easy to aggregate and analyze results across dozens of platforms.
The dictionary serves as the universal data contract between individual modules and the reporting engine in holehe/core.py. Regardless of whether you're checking Twitter, Instagram, or a niche transport service like BlaBlaCar, the output structure remains identical.
The Six Fields in Every Holehe Result Dictionary
| Key | Type | Description |
|---|---|---|
name |
str |
Module identifier matching the service (e.g., twitter, instagram, blablacar). |
rateLimit |
bool |
True if the service blocked the request due to rate limiting. |
exists |
bool |
True if the email is registered on that service. |
emailrecovery |
str or None |
Partially masked recovery email, if exposed by the service. |
phoneNumber |
str or None |
Partially masked recovery phone number, if exposed. |
others |
any or None |
Extension point for additional module-specific data. |
This schema is documented in the repository's README under the Module Output section and enforced by convention across all module implementations.
Where the Result Dictionary Is Built in the Source Code
Core Implementation Pattern
Each Holehe module constructs its result dictionary at the end of its main function. For example, in holehe/modules/social_media/twitter.py and holehe/modules/transport/blablacar.py, you'll see code following this pattern:
out.append({
"name": "twitter",
"rateLimit": is_rate_limited,
"exists": account_found,
"emailrecovery": masked_email,
"phoneNumber": masked_phone,
"others": None
})
The out parameter is a list passed by the caller (managed in holehe/core.py) that collects all result dictionaries for final aggregation.
Key Source Files
holehe/core.py– Orchestrates module execution and aggregates dictionaries into reports.holehe/modules/social_media/twitter.py– Social media module implementing the result format.holehe/modules/transport/blablacar.py– Transport module with identical dictionary construction.README.md– Documents the expected output structure for contributors and users.
Working with Holehe Result Dictionaries in Python
Basic Programmatic Usage
import httpx
import trio
from holehe.modules.social_media.twitter import twitter
async def check_single_service(email: str):
results = []
async with httpx.AsyncClient() as client:
await twitter(email, client, results)
# Returns the standard 6-key dictionary
return results[0]
# Execute
result = trio.run(check_single_service, "test@example.com")
print(result)
Expected output:
{
'name': 'twitter',
'rateLimit': False,
'exists': True,
'emailrecovery': None,
'phoneNumber': None,
'others': None
}
Processing Multiple Results
from holehe.core import import_submodules
from holehe.modules import module
async def check_email_full(email: str):
async with httpx.AsyncClient() as client:
modules = import_submodules()
all_results = []
for mod in modules:
out = []
try:
await mod(email, client, out)
all_results.extend(out)
except Exception:
continue # Skip failed modules
# Filter and analyze results
found_accounts = [r for r in all_results if r['exists']]
rate_limited = [r for r in all_results if r['rateLimit']]
return {
'total_checked': len(all_results),
'accounts_found': len(found_accounts),
'rate_limited_services': [r['name'] for r in rate_limited],
'recovery_emails': [r['emailrecovery'] for r in all_results if r['emailrecovery']]
}
Checking for Recovery Information
The emailrecovery and phoneNumber fields are particularly valuable for osint investigations. Services like Instagram occasionally expose partial recovery data:
async def check_recovery_data(email: str):
from holehe.modules.social_media.instagram import instagram
results = []
async with httpx.AsyncClient() as client:
await instagram(email, client, results)
result = results[0]
if result['exists']:
print(f"Account found on {result['name']}")
if result['emailrecovery']:
print(f" Recovery email pattern: {result['emailrecovery']}")
# Example output: "ex****e@gmail.com"
if result['phoneNumber']:
print(f" Recovery phone pattern: {result['phoneNumber']}")
# Example output: "0*******78"
return result
Interpreting Field Values Correctly
Understanding rateLimit vs exists
These boolean flags operate independently:
rateLimit: True– The service blocked the request;existsis unreliable.exists: True– Confirmed registration, but check ifrateLimitisFalse.- Both
False– Confirmed no account found (or service unavailable).
Always check rateLimit before trusting exists:
def is_confirmed_account(result: dict) -> bool:
return result['exists'] and not result['rateLimit']
The others Extension Field
While currently None in most modules, others allows future expansion without breaking the schema. Custom modules can use it to return:
- Profile URLs
- Username handles
- Account creation dates
- Geo-location hints
Maintain backward compatibility by keeping the six core fields present even when extending.
Summary
- Every Holehe module returns identical dictionary keys:
name,rateLimit,exists,emailrecovery,phoneNumber, andothers. - The schema is enforced by convention across all modules in
holehe/modules/and documented inREADME.md. holehe/core.pyorchestrates execution while individual service modules insocial_media/,transport/, and other categories implement the format.- Programmatic access requires passing an
outlist that receives result dictionaries; usehttpx.AsyncClientfor HTTP handling. - Recovery data fields (
emailrecovery,phoneNumber) contain masked patterns, not full credentials. - Always validate
rateLimitbefore trusting positiveexistsresults.
Frequently Asked Questions
What does rateLimit: True mean in a Holehe result dictionary?
A True value indicates the target service blocked the request due to too many queries from your IP address. When rateLimit is True, the exists field becomes unreliable—you cannot determine whether the account exists because the service refused to respond. Wait before retrying or rotate your IP address.
Can Holehe result dictionaries contain additional custom keys?
No. All modules must return exactly the six specified keys to maintain compatibility with holehe/core.py and downstream tools. The others field exists specifically for extensibility—place any supplementary data there rather than adding new top-level keys.
How do I extract just the services where an account exists?
Filter the results list using a list comprehension that checks both exists and rateLimit:
confirmed = [
r['name'] for r in results
if r['exists'] and not r['rateLimit']
]
This pattern appears throughout the Holehe codebase when generating summary reports.
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 →