How to Use holehe as a Python API: Programmatic OSINT Integration

You can use holehe as a Python API by importing functions from holehe.core and holehe.modules to programmatically execute the same 200+ site checks that the CLI performs, receiving structured JSON-like results without spawning subprocesses.

The megadose/holehe repository is an open-source email OSINT (Open Source Intelligence) tool designed to identify account registration across hundreds of websites. While the command-line interface is the most common entry point, the codebase is structured as a Python package that allows you to use holehe as a Python API, embedding its reconnaissance engine directly into your own scripts, data pipelines, or security automation workflows.

Core Architecture for API Usage

The library separates concerns between module discovery, HTTP client management, and execution orchestration. Understanding these layers is essential for stable programmatic integration.

Module Discovery via holehe.core

According to the source code in [holehe/core.py](https://github.com/megadose/holehe/blob/master/holehe/core.py), the package exposes three critical functions for API usage:

  • import_submodules(package) – Dynamically walks the holehe.modules package tree and imports every site-specific check function.
  • get_functions(modules, args=None) – Filters the imported modules to extract only the callable check functions, returning a list of coroutines ready for execution.
  • launch_module(module, email, client, out) – An async wrapper that executes a single site check, handles exceptions gracefully, and appends a standardized result dictionary to your output list.

The Async HTTP Client

Every module in holehe.modules expects an httpx.AsyncClient instance as its second argument. The client handles all network I/O, and you should instantiate it once with your desired timeout configuration, then pass it to all concurrent checks. The library uses httpx rather than requests to support high-concurrency async patterns.

Step-by-Step API Implementation

To use holehe as a Python API, follow this workflow based on the CLI implementation in holehe/core.py:

  1. Import all site modules using import_submodules("holehe.modules") to load the 200+ site checkers.

  2. Extract check functions via get_functions(modules) to obtain a list of callable coroutines.

  3. Initialize the HTTP client with httpx.AsyncClient(timeout=10) (or your preferred timeout).

  4. Execute checks concurrently using an async nursery (the example below uses trio) or asyncio.gather, calling launch_module for each site function.

  5. Collect standardized results from the mutable out list passed to launch_module, which will contain dictionaries with keys including name, domain, exists, emailrecovery, and rateLimit.

Complete Working Example

Below is a self-contained implementation that demonstrates how to query an email address against all supported platforms programmatically:

import asyncio
import httpx
import trio
from holehe.core import import_submodules, get_functions, launch_module
from holehe.instruments import TrioProgress

async def check_email_osint(email: str, timeout: int = 10):
    """
    Run holehe checks against *email* using the Python API.
    Returns a list of result dictionaries.
    """
    # 1️⃣ Load all site modules from holehe.modules

    modules = import_submodules("holehe.modules")
    
    # 2️⃣ Extract the callable site functions

    websites = get_functions(modules)
    
    # 3️⃣ Prepare the async HTTP client

    client = httpx.AsyncClient(timeout=timeout)
    
    # 4️⃣ Container for results

    out = []
    
    # 5️⃣ Optional: Add progress instrumentation

    instrument = TrioProgress(len(websites))
    trio.lowlevel.add_instrument(instrument)
    
    # 6️⃣ Execute all checks concurrently

    async with trio.open_nursery() as nursery:
        for site_fn in websites:
            nursery.start_soon(launch_module, site_fn, email, client, out)
    
    # 7️⃣ Cleanup

    trio.lowlevel.remove_instrument(instrument)
    await client.aclose()
    
    # 8️⃣ Return sorted results

    return sorted(out, key=lambda x: x["name"])

# ----------------------------------------------------------------------

# Example usage

if __name__ == "__main__":
    target_email = "alice@example.com"
    results = trio.run(check_email_osint, target_email)
    
    # Display results

    for site in results:
        status = "[+]" if site["exists"] else "[-]"
        print(f"{status} {site['domain']}: Account exists = {site['exists']}")

Understanding the Result Structure

Each entry in the returned list is a standardized dictionary defined in the site modules (e.g., [holehe/modules/social_media/twitter.py](https://github.com/megadose/holehe/blob/master/holehe/modules/social_media/twitter.py)):

{
    "name": "twitter",
    "domain": "twitter.com",
    "exists": True,
    "emailrecovery": None,
    "phoneNumber": None,
    "rateLimit": False,
    "error": False,
    "others": {"FullName": "Alice Smith"}
}
  • exists: Boolean indicating whether the email is registered on the platform.
  • emailrecovery: Partial email address if the site exposes recovery information.
  • phoneNumber: Partial phone number if exposed by the service.
  • rateLimit: True if the module detected throttling or blocking.
  • others: Dictionary containing additional metadata scraped by the module (e.g., full name, profile URL).

Key Source Files for API Developers

File Purpose API Relevance
holehe/core.py Defines import_submodules, get_functions, and launch_module; contains the main async driver logic. Core API entry points
holehe/modules/__init__.py Package initialization that enables dynamic module loading. Required for discovery
holehe/instruments.py Provides TrioProgress for real-time progress tracking. Optional UI enhancement
holehe/localuseragent.py Supplies randomized User-Agent strings via ua variable. Useful for custom HTTP clients

Summary

  • holehe.core exposes the essential functions (import_submodules, get_functions, launch_module) needed to use holehe as a Python API.
  • The API requires an httpx.AsyncClient and async execution context (trio or asyncio) to run the 200+ built-in site checks concurrently.
  • Results are returned as standardized dictionaries containing exists, emailrecovery, phoneNumber, and rateLimit fields.
  • You can integrate the library without CLI dependencies by importing directly from the package structure defined in megadose/holehe.

Frequently Asked Questions

Do I need to install the CLI to use the holehe Python API?

No. Once you install holehe via pip install holehe, you can import holehe.core and holehe.modules directly in your Python scripts. The CLI in holehe/core.py is simply a wrapper around these same API functions that parses command-line arguments.

Can I run checks against specific websites only instead of all modules?

Yes. While get_functions(modules) returns all available site checkers by default, you can filter the returned list before execution. Each function object has a __module__ attribute containing the site name (e.g., "holehe.modules.social_media.twitter"), allowing you to whitelist or blacklist specific platforms programmatically.

How does the API handle rate limiting and timeouts?

Each site module sets rateLimit to True in the result dictionary when it detects throttling (HTTP 429 or similar). The httpx.AsyncClient passed to launch_module controls the timeout; if a request exceeds this limit, the exception is caught and recorded in the error field without crashing the entire batch.

Is the holehe Python API compatible with standard asyncio?

Yes. While the provided example uses trio for concurrency (matching the CLI's default behavior), the underlying site check functions are standard async coroutines. You can replace the trio.open_nursery() pattern with asyncio.gather() or asyncio.TaskGroup if you prefer using asyncio for your event loop.

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 →