How to Run Holehe with a List of Emails: 4 Bulk Processing Methods

Holehe does not have a built-in -f or -i flag for batch input; you must call it repeatedly via shell loops, xargs, parallel, or a Python wrapper that consumes the holehe.core library.

The open-source OSINT tool Holehe is designed to check whether an email address is registered on hundreds of websites. However, as implemented in megadose/holehe, the command-line interface only accepts one email per execution. This guide explains how to run Holehe with a list of emails using proven bulk processing techniques backed by the source code architecture.


Why Holehe Requires External Bulk Processing

In holehe/core.py, the ArgumentParser defines a single positional argument for the email address:


# Simplified excerpt from holehe/core.py

parser.add_argument("email", help="Email address to check")
args = parser.parse_args()

# args.email is passed to the async execution engine

The core orchestration logic — creating an httpx.AsyncClient, dispatching to modules under holehe/modules/, and aggregating results — is built around this single-email assumption. Each module (e.g., instagram.py, twitter.py) receives the same client and email, returning a standardized dictionary with fields like name, exists, and emailrecovery.

Because no native batch mode exists, you handle lists externally. Below are four reliable methods.


Method 1: Bash While-Read Loop (Simplest)

The most portable approach reads a file line-by-line and invokes Holehe sequentially.

while read email; do
    holehe "$email"
done < emails.txt

Pros: Works on any POSIX shell; easy to debug.

Cons: Synchronous execution; large lists are slow.


Method 2: xargs for Streamlined Sequential Processing

xargs eliminates the explicit loop and handles argument passing efficiently.

cat emails.txt | xargs -n1 holehe
  • -n1 ensures one email per Holehe invocation
  • Automatically handles whitespace and special characters when combined with -0

For safer handling of odd characters:

tr '\n' '\0' < emails.txt | xargs -0 -n1 holehe

Method 3: GNU Parallel for Speed

When scanning hundreds or thousands of emails, parallel execution dramatically reduces wall-clock time.

parallel holehe {} :::: emails.txt
  • {} is the placeholder for each email
  • :::: reads from file (alternative to piping)
  • Control concurrency with -j (e.g., -j10 for 10 parallel jobs)

Example with rate limiting and progress bar:

parallel --bar -j8 holehe {} :::: emails.txt > results.jsonl 2> errors.log

Method 4: Python Library Integration

For custom workflows, import holehe.core directly instead of shelling out. The internal run_all_modules function (located in holehe/core.py) executes every available module against a single email.

import asyncio
import httpx
from holehe.core import run_all_modules

async def check_email(email: str):
    """Run all Holehe modules against one email address."""
    async with httpx.AsyncClient() as client:
        results = await run_all_modules(email, client)
    return {"email": email, "services": results}

async def main(emails: list[str]):
    """Process multiple emails concurrently."""
    tasks = [check_email(e) for e in emails]
    return await asyncio.gather(*tasks)

# Example usage

emails = ["alice@example.com", "bob@example.org", "charlie@example.net"]
results = asyncio.run(main(emails))

# Output processing

for r in results:
    print(f"\n{r['email']}:")
    for service in r['services']:
        status = "✓" if service.get('exists') else "✗"
        print(f"  {status} {service['name']}")

Key integration points:

  • run_all_modules(email, client) is the core dispatcher found in holehe/core.py
  • Pass a shared httpx.AsyncClient or create fresh clients per email depending on rate-limit needs
  • Results are list[dict] with standardized keys: name, domain, method, frequent_rate_limit, rate_limit, exists, emailrecovery, phoneNumber, others

Windows PowerShell Alternative

For Windows environments without WSL, process lists with ForEach-Object:

Get-Content .\emails.txt | ForEach-Object { holehe $_ }

Or with parallel execution using ForEach-Object -Parallel (PowerShell 7+):

Get-Content .\emails.txt | ForEach-Object -Parallel { holehe $_ } -ThrottleLimit 8

Summary

  • No native batch mode: Holehe's CLI in holehe/core.py accepts exactly one email argument per run.
  • Shell loops: Use while read for simplicity, xargs -n1 for cleaner syntax, or parallel for performance.
  • Python library: Import run_all_modules from holehe.core to build custom async pipelines with full control over concurrency and output formatting.
  • Architecture: All methods ultimately rely on the same module system under holehe/modules/, where each service check receives the email and an httpx.AsyncClient via the core dispatcher.

Frequently Asked Questions

Can Holehe read emails from a CSV or JSON file directly?

No. Holehe has no built-in file parser for structured data. You must extract email addresses first using standard tools: cut -d',' -f1 accounts.csv for CSV, or jq -r '.[].email' data.json for JSON, then pipe into any method above.

Does running Holehe in parallel trigger rate limits?

Yes. Many modules in holehe/modules/ include frequent_rate_limit flags in their return dictionaries. When using parallel or Python asyncio.gather, start with low concurrency (-j3 or 5 simultaneous tasks) and monitor for rate_limit: True responses. The source code shows modules self-report rate-limiting status, but do not automatically throttle.

Is there a way to get structured JSON output for bulk results?

The CLI outputs formatted text to STDOUT. For machine-readable bulk results, use the Python library approach shown above, or redirect CLI output and parse with grep/jq:

parallel holehe {} :::: emails.txt 2>&1 | jq -R --slurp 'split("\n") | map(select(length > 0))'

The cleanest solution remains direct Python integration where you control serialization.

What version of Holehe supports run_all_modules?

The run_all_modules helper and httpx-based async architecture are present in Holehe 1.60+ (current as of the megadose/holehe repository). Earlier versions used requests and synchronous execution with different internal APIs. Verify your install with holehe --version.

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 →