Holehe Async Module Function Signature: The Standardized API for Email OSINT

Every asynchronous module function in the Holehe repository follows the exact signature async def <service_name>(email: str, client: httpx.AsyncClient, out: list) -> None, enabling uniform email existence checks across 60+ services.

Holehe is an open-source OSINT tool that checks where an email address is registered online. Its architecture relies on a modular design where each service interrogator lives in its own Python file under holehe/modules/. To allow the core runner to execute dozens of checks concurrently without custom logic for each site, every module exposes an identical asynchronous function signature.

The Universal Three-Parameter Pattern

According to the source code in megadose/holehe, all public module functions implement this strict interface:

async def <service_name>(email: str, client: httpx.AsyncClient, out: list) -> None

The parameters serve distinct roles:

  • email – The target address to probe, passed as a standard Python string.
  • client – An httpx.AsyncClient (or compatible) instance, typically pre-configured with random user-agents from holehe/localuseragent.py and optional proxy settings.
  • out – A mutable list passed by reference that the function appends a result dictionary to. This dictionary contains keys such as name, domain, method, exists, rateLimit, and error.

This signature appears consistently across all module categories, from social media scanners in holehe/modules/social_media/twitter.py to shopping platforms in holehe/modules/shopping/amazon.py.

Module Categories and File Structure

The repository organizes modules into 20 functional categories. While each file contains unique logic for bypassing CSRF tokens or parsing JSON responses, the function signature remains invariant.

Social Media and Communication

Services checking major platforms follow the standard signature:

Software and Development

Programming-related services use the same interface:

Shopping and E-commerce

Commercial platforms adhere to the pattern:

Additional Categories

The uniform signature extends to niche categories including:

  • Music: spotify, soundcloud, lastfm in holehe/modules/music/
  • Productivity: evernote, anydo in holehe/modules/productivity/
  • Medical: caringbridge, sevencups in holehe/modules/medical/
  • Payment: venmo in holehe/modules/payment/venmo.py

Internal Helper Functions vs. Public API

While the public-facing module functions maintain the strict three-parameter contract, some modules define internal async helpers with extended signatures for multi-step authentication flows. For example, holehe/modules/products/samsung.py contains get_phone_number, which accepts additional cookies and headers parameters. These helpers are implementation details used within the file and are not called by the core runner.

How holehe/core.py Leverages the Signature

The uniformity of the async module function signature enables the orchestration logic in holehe/core.py to discover and execute modules dynamically. The runner introspects the holehe/modules/ directory, imports each function, and schedules concurrent tasks using asyncio.gather() without branching logic:


# Conceptual flow from holehe/core.py

tasks = []
for module_function in discovered_modules:
    tasks.append(module_function(email, client, results_list))
await asyncio.gather(*tasks)

Because every function accepts client and out identically, the core engine shares a single httpx.AsyncClient instance across all checks and aggregates results into a single list efficiently.

Practical Example: Direct Module Invocation

You can import and call any module function directly when building custom workflows, provided you supply the three required arguments:

import httpx
import asyncio
from holehe.modules.social_media.twitter import twitter

async def check_twitter():
    async with httpx.AsyncClient() as client:
        results = []
        await twitter("target@example.com", client, results)
        # results now contains: [{'name': 'twitter', 'exists': True/False, ...}]

        print(results)

asyncio.run(check_twitter())

This pattern works identically for any module in the repository, from holehe/modules/mails/google.py to holehe/modules/porn/pornhub.py.

Summary

  • Standard signature: All async module functions use async def func(email, client, out).
  • Location: Modules reside in categorized subdirectories under holehe/modules/.
  • Parameters: email (str), client (httpx.AsyncClient), and out (list).
  • Return value: None; results are appended to the mutable out list.
  • Internal helpers: Some modules define private functions with extra parameters, but these are not part of the public API consumed by holehe/core.py.

Frequently Asked Questions

What is the exact async function signature for Holehe modules?

Every module exposes async def <service_name>(email: str, client: httpx.AsyncClient, out: list) -> None. This signature is enforced across all 60+ services, allowing the core runner to invoke each function without custom adapters.

Why does Holehe use a mutable list instead of returning values?

The out list parameter enables safe concurrent aggregation. When asyncio.gather() runs dozens of module functions simultaneously, each appends its result dictionary to the shared list without race conditions, avoiding the need for complex return-value collation logic in holehe/core.py.

Can I use a different HTTP client instead of httpx.AsyncClient?

The type hint specifies httpx.AsyncClient, but any compatible async client implementing .get(), .post(), and similar coroutine methods will work, provided it supports the same interface. However, the official holehe distribution pre-configures httpx.AsyncClient instances with randomized user-agents from holehe/localuseragent.py.

How do I add a custom module to Holehe?

Create a Python file in the appropriate holehe/modules/<category>/ subdirectory. Define an async function matching the standard signature (email, client, out), append your result dictionary to out, and ensure the function name matches the service identifier. The auto-discovery mechanism in holehe/core.py will include it automatically on the next run.

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 →