Can Holehe Be Used Programmatically in Python? 3 Methods to Integrate OSINT Checks

Yes, Holehe can be used programmatically in Python as a pure-Python library with full async support, no subprocess or external binaries required.

Holehe is an open-source email OSINT tool by megadose that checks whether an email address is registered on hundreds of websites. While commonly used as a CLI tool, its modular architecture makes it ideal for Python automation, custom pipelines, and integration into larger security workflows.

Why Use Holehe Programmatically?

Running Holehe from Python code unlocks several advantages over CLI usage:

  • Custom filtering – Process only specific site categories or result types
  • Result transformation – Convert output to JSON, database records, or alerts
  • Workflow integration – Embed checks into SIEM pipelines, web apps, or scheduled jobs
  • Concurrent control – Fine-tune async execution with Trio primitives

The codebase is structured around a simple contract: every site check is an async function with signature (email, client, out) in holehe/modules/.

Method 1: Check a Single Site Directly

For targeted investigations, import and call individual modules. This is the most lightweight approach.

import trio
import httpx
from holehe.modules.social_media.snapchat import snapchat

async def check_snapchat():
    email = "target@example.com"
    results = []
    
    async with httpx.AsyncClient() as client:
        await snapchat(email, client, results)
    
    print(results)
    # [{'name': 'snapchat', 'exists': True, 'emailrecovery': None, ...}]

trio.run(check_snapchat)

Each module in holehe/modules/ follows this pattern. The out list receives standardized result dictionaries containing:

Key Meaning
name Site identifier (e.g., "snapchat")
exists Boolean indicating registration found
emailrecovery Partial recovery email if exposed
rateLimit Whether the check hit rate limiting

Method 2: Run Full Multi-Site Scans

To replicate the complete Holehe behavior programmatically, use the core orchestration utilities from holehe/core.py.

import trio
import httpx
from holehe.core import import_submodules, get_functions, launch_module

async def full_holehe_scan(email):
    # Dynamically load all site check modules

    modules = import_submodules("holehe.modules")
    websites = get_functions(modules)  # Extract callable check functions

    
    results = []
    
    async with httpx.AsyncClient() as client:
        # Run all checks concurrently with Trio nursery

        async with trio.open_nursery() as nursery:
            for check_func in websites:
                nursery.start_soon(launch_module, check_func, email, client, results)
    
    return results

# Execute scan

output = trio.run(full_holehe_scan, "target@example.com")

for site_result in output:
    print(f"{site_result['name']}: {site_result.get('exists', 'unknown')}")

The launch_module wrapper in holehe/core.py handles exceptions and ensures partial failures don't crash the entire scan.

Method 3: Invoke the High-Level CLI Wrapper

For quick scripts that need standard CLI behavior without shelling out, call main() directly.

from holehe.core import main

if __name__ == "__main__":
    # Behaves identically to: holehe target@example.com

    main()

Important: main() parses sys.argv, so you must set arguments before calling:

import sys
from holehe.core import main

sys.argv = ["holehe", "target@example.com", "--only-used"]
main()

This approach respects all CLI flags including --only-used, --no-clear, and timeout settings.

Key Implementation Files Reference

Understanding these source files helps with custom integrations:

Async Architecture: Trio and httpx

Holehe is built on Trio for structured concurrency and httpx for HTTP. This matters for programmatic use:

  • Never mix asyncio and Trio – Use trio.run() or trio's guest mode exclusively
  • Share the client – Pass one httpx.AsyncClient to all checks for connection pooling
  • Nursery-based cancellation – Failed checks cancel cleanly without resource leaks

For sync-only codebases, run Trio in a thread:

import trio

def sync_wrapper(email):
    return trio.run(full_holehe_scan, email)

result = sync_wrapper("target@example.com")

Summary

  • Holehe is fully importable as a Python library in megadose/holehe
  • Three integration patterns: single module, full orchestration, or CLI wrapper
  • Core functions in holehe/core.py handle module loading and concurrent execution
  • Result format is standardized across all 100+ site checks
  • No subprocess required – pure Python with Trio/httpx async stack

Frequently Asked Questions

Can I use Holehe with standard asyncio instead of Trio?

No. Holehe is built exclusively on Trio for structured concurrency. While Trio can run as a guest inside asyncio using trio.lowlevel.start_guest_run, the library itself requires Trio primitives. Mixing asyncio coroutines directly will cause runtime errors.

How do I filter results to only show confirmed accounts?

Check the exists key in result dictionaries. When using the programmatic API, filter the output list:

confirmed = [r for r in results if r.get("exists") is True]

The --only-used CLI flag performs this filtering automatically when using main().

Is rate limiting handled automatically?

Partially. Individual modules detect rate limits and set rateLimit: True in results, but retry logic is minimal. For production use, implement exponential backoff between calls or proxy rotation via httpx.AsyncClient configuration.

Can I add custom site checks without modifying the source?

Yes. Create a module matching the (email, client, out) signature and add it to holehe/modules/your_category/. The import_submodules function in holehe/core.py dynamically discovers all modules at runtime, so custom checks integrate automatically.

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 →