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:

Summary

  • Every Holehe module returns an identical nine-field dictionary to ensure consistent parsing across all services
  • The exists boolean is the primary indicator of whether an email is registered on a given platform
  • Rate-limiting is tracked via two fields: frequent_rate_limit for known aggressive services, rateLimit for the current request status
  • Placeholder fields (emailrecovery, phoneNumber, others) reserve schema space for future data extraction capabilities
  • The out list pattern enables both individual module testing and bulk processing through holehe.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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →