# How to Check Multiple Email Addresses with Holehe: Batch OSINT Verification

> Learn how to check multiple email addresses with Holehe for efficient OSINT verification. Discover Python and shell scripting methods to batch process emails and gather valuable intelligence quickly.

- Repository: [Palenath/holehe](https://github.com/megadose/holehe)
- Tags: how-to-guide
- Published: 2026-08-22

---

**You can check multiple email addresses with Holehe by asynchronously invoking the `run()` function from [`holehe/core.py`](https://github.com/megadose/holehe/blob/main/holehe/core.py) inside a Python loop, or by using shell scripting to iterate through a list and call the CLI entry point defined in [`setup.py`](https://github.com/megadose/holehe/blob/main/setup.py).**

Holehe is an asynchronous OSINT framework that verifies email registration across 120+ online platforms. When you need to check multiple email addresses with Holehe programmatically, you leverage the same modular engine that powers the CLI—found in `megadose/holehe`—to process batches efficiently without blocking I/O operations.

## Programmatic Batch Verification (Python API)

The most efficient way to process multiple addresses uses the core engine directly rather than spawning separate CLI processes. In [`holehe/core.py`](https://github.com/megadose/holehe/blob/main/holehe/core.py), the `run()` function orchestrates the `httpx.AsyncClient` and dynamically loads all service modules under `holehe/modules/*`.

### Sequential Processing with the Core Runner

For reliable bulk checking, import `run` and await it for each email in your list. This ensures proper session management and cleanup for each address.

```python
import trio
from holehe.core import run

async def check_multiple_emails(email_list):
    results = []
    for email in email_list:
        # Run the full suite of modules for each email

        result = await run(email)
        results.append(result)
    return results

emails = ["test1@example.com", "test2@gmail.com", "test3@outlook.com"]
trio.run(lambda: check_multiple_emails(emails))

```

Each invocation loads every module (e.g., [`holehe/modules/social_media/twitter.py`](https://github.com/megadose/holehe/blob/main/holehe/modules/social_media/twitter.py), [`holehe/modules/mails/google.py`](https://github.com/megadose/holehe/blob/main/holehe/modules/mails/google.py)) and aggregates their standardized output dictionaries containing keys like `exists`, `rateLimit`, and `emailrecovery`.

### Concurrent Service Checking

To accelerate batch operations, target specific high-priority services concurrently rather than running the full suite sequentially. Import individual modules and use `trio` nurseries or `asyncio.gather()`.

```python
import trio
import httpx
from holehe.modules.social_media.twitter import twitter
from holehe.modules.mails.google import google

async def check_emails_concurrent(email_list):
    async with httpx.AsyncClient() as client:
        tasks = []
        for email in email_list:
            # Check specific services for multiple emails simultaneously

            tasks.append(twitter(email, client, []))
            tasks.append(google(email, client, []))
        
        results = await trio.gather(*tasks)
        return results

# Process all emails against Twitter and Google concurrently

trio.run(lambda: check_emails_concurrent(["a@example.com", "b@test.com"]))

```

## Command-Line Batch Processing

When you cannot use Python directly, the CLI entry point defined in [`setup.py`](https://github.com/megadose/holehe/blob/main/setup.py) and implemented in [`holehe/__main__.py`](https://github.com/megadose/holehe/blob/main/holehe/__main__.py) accepts a single email argument. Process multiple addresses using a shell loop.

```bash

# Check multiple emails via shell loop

for email in test@example.com admin@site.com info@company.com
do
    echo "Checking $email..."
    holehe "$email"
done

```

For larger lists from a file:

```bash
while read email; do
    holehe "$email" >> results.json
done < emails.txt

```

## Parsing Batch Results

Whether using the CLI or Python API, each check returns a list of dictionaries with consistent schema fields:

- **name**: Service identifier (e.g., `twitter`, `google`)
- **exists**: Boolean indicating if the email is registered
- **rateLimit**: Boolean flag if the service temporarily blocked the check
- **emailrecovery**: Partial recovery email hint (if exposed)
- **phoneNumber**: Partial phone number hint (if exposed)

When batch processing programmatically, aggregate these lists into a master dataset for analysis.

## Summary

- **Programmatic approach**: Import `run` from [`holehe/core.py`](https://github.com/megadose/holehe/blob/main/holehe/core.py) to check multiple email addresses with Holehe asynchronously, avoiding process spawn overhead.
- **Modular targeting**: Import specific modules from `holehe/modules/*` (e.g., [`twitter.py`](https://github.com/megadose/holehe/blob/main/twitter.py), [`google.py`](https://github.com/megadose/holehe/blob/main/google.py)) to run concurrent checks against priority services only.
- **CLI limitation**: The `holehe` command processes one address per invocation; use shell loops for batch CLI execution.
- **Data structure**: Each module returns standardized dictionaries with `exists`, `rateLimit`, and recovery information, making aggregation straightforward.

## Frequently Asked Questions

### Can the Holehe CLI accept multiple emails in one command?

The CLI entry point in [`holehe/__main__.py`](https://github.com/megadose/holehe/blob/main/holehe/__main__.py) and [`setup.py`](https://github.com/megadose/holehe/blob/main/setup.py) parses a single email argument. For batch operations, wrap the command in a shell loop or use the Python API to iterate over lists without spawning new processes for each address.

### How do I prevent rate limiting when checking multiple emails?

Holehe modules return a `rateLimit` boolean in their result dictionaries. When batch processing, implement delays between requests or limit concurrent connections when using `asyncio.gather()` or `trio` nurseries to avoid triggering service protections.

### What is the fastest method to check 50+ emails with Holehe?

Use the Python API importing `run` from `holehe.core` rather than CLI loops. This keeps the `httpx.AsyncClient` session alive across checks and eliminates the overhead of repeatedly loading all modules from `holehe/modules/*` in separate processes.

### Does Holehe store historical data when processing multiple addresses?

No, Holehe operates statelessly. Each execution—whether checking one email or iterating through hundreds—returns results to stdout or the calling function without persistence. You must implement your own storage solution when batch processing multiple email addresses.