# How Holehe Checks Email Existence Without Sending Notifications

> Discover how Holehe checks email existence without sending notifications. It queries public APIs for instant existence data, bypassing email confirmations.

- Repository: [Palenath/holehe](https://github.com/megadose/holehe)
- Tags: internals
- Published: 2026-08-24

---

**Holehe verifies email registration status across hundreds of services by querying public API endpoints—such as email-availability checks, registration validations, and password-reset interfaces—that return existence data via immediate HTTP responses without dispatching notification emails.**

Holehe is an open-source OSINT tool maintained in the `megadose/holehe` repository that checks whether an email address is registered on over 120 online platforms. Unlike conventional methods that trigger password-reset emails or verification messages, Holehe performs **silent email existence checks** by analyzing the immediate HTTP responses from service-specific endpoints, ensuring the target never receives an alert.

## Three Silent Detection Techniques

Holehe modules exploit three distinct categories of public endpoints that reveal account existence without initiating email workflows. Each technique relies on parsing JSON responses or HTTP status codes rather than following through with actions that would cause the target service to send messages.

### Email Availability APIs

Many platforms expose dedicated endpoints that check email uniqueness during registration flows. In [`holehe/modules/social_media/twitter.py`](https://github.com/megadose/holehe/blob/main/holehe/modules/social_media/twitter.py), the module sends a POST request to `https://api.twitter.com/i/users/email_available.json` with the target email in the request body. The server responds with a JSON object containing an `email_available` boolean flag. When the value is `false`, the email exists in Twitter's database. This operation is purely a database lookup that returns a status flag; the endpoint never triggers a verification email or password-reset message.

### Registration Form Validation

Services like Facebook and Spotify validate registration input before creating accounts. Holehe submits the target email to sign-up endpoints as if initiating a new registration. In [`holehe/modules/social_media/facebook.py`](https://github.com/megadose/holehe/blob/main/holehe/modules/social_media/facebook.py), the module posts to the registration validation endpoint, which returns error messages such as "email already in use" when the address exists. This server-side validation occurs before any account creation or email dispatch, allowing Holehe to capture the existence status from the error response without completing the registration process.

### Password Reset Endpoint Probing

Some services expose password-reset interfaces that return distinct responses for registered versus unknown emails. In [`holehe/modules/software/adobe.py`](https://github.com/megadose/holehe/blob/main/holehe/modules/software/adobe.py), the module calls the password-reset URL with the target email and analyzes the response body. While some services return generic "reset link sent" messages regardless of email existence, others return explicit "email not found" responses or different HTTP status codes when the address does not exist. Holehe reads these differential responses without requesting the actual reset link generation, thereby avoiding the email delivery mechanism entirely.

## Core Architecture and Async Execution

The central orchestration logic resides in [`holehe/core.py`](https://github.com/megadose/holehe/blob/main/holehe/core.py), which manages concurrent execution across all service modules using an asynchronous architecture.

The system initializes through `import_submodules`, which dynamically loads every module in the `holehe/modules` directory, and `get_functions`, which extracts the async check functions from each submodule. The main execution flow creates an `httpx.AsyncClient` instance and passes it to `launch_module`, which executes checks concurrently via **Trio**—a structured concurrency library for Python.

Each module follows a standardized asynchronous signature:

```python
async def <service_name>(email, client, out):
    # Implementation sends GET/POST/HEAD request

    # Parses response for existence indicators

    out.append({
        "domain": "<service>.com",
        "exists": True/False,
        "emailrecovery": None or str,
        "rateLimit": False,
        "error": False,
        "others": {}
    })

```

The `out` parameter is a list that collects dictionaries containing the check results. After all modules complete, the CLI formatter in [`holehe/core.py`](https://github.com/megadose/holehe/blob/main/holehe/core.py) displays results with visual indicators: a **green `[+]`** indicates the email exists on that service, while a **magenta `[-]`** indicates it does not.

## Module Implementation Example

Individual service modules implement the detection logic using service-specific endpoints. The following pattern demonstrates how Holehe checks Twitter without triggering notifications, simplified from [`holehe/modules/social_media/twitter.py`](https://github.com/megadose/holehe/blob/main/holehe/modules/social_media/twitter.py):

```python
async def twitter(email, client, out):
    headers = {
        "User-Agent": "Mozilla/5.0...",
        "X-Requested-With": "XMLHttpRequest"
    }
    
    data = {
        "email": email,
        "account_platform": "web"
    }
    
    response = await client.post(
        "https://api.twitter.com/i/users/email_available.json",
        headers=headers,
        data=data
    )
    
    json_response = response.json()
    exists = json_response.get("email_available") is False
    
    out.append({
        "domain": "twitter.com",
        "exists": exists,
        "emailrecovery": None,
        "rateLimit": False,
        "error": False,
        "others": json_response
    })

```

The module uses [`holehe/localuseragent.py`](https://github.com/megadose/holehe/blob/main/holehe/localuseragent.py) to rotate User-Agent strings and avoid simple bot detection. Because the function only inspects the immediate JSON response and does not proceed with any workflow that would generate emails, the target remains unaware of the check.

## Summary

- **Silent HTTP Inspection**: Holehe queries public endpoints that return email existence as JSON flags or HTTP status codes, never completing workflows that trigger email delivery.
- **Three Primary Vectors**: The tool leverages email-availability APIs, registration validation errors, and password-reset differential responses to determine account status.
- **Scalable Async Architecture**: [`holehe/core.py`](https://github.com/megadose/holehe/blob/main/holehe/core.py) orchestrates concurrent checks across 120+ services using `httpx.AsyncClient` and Trio structured concurrency.
- **Standardized Output**: All modules populate a consistent dictionary structure with `exists`, `emailrecovery`, and `rateLimit` fields, formatted for command-line display.
- **No Notification Risk**: Because Holehe stops after receiving the initial HTTP response and does not follow through with reset or verification requests, target users receive zero notifications.

## Frequently Asked Questions

### Does Holehe trigger password reset emails when checking accounts?

No. Holehe queries password-reset endpoints but does not request the actual reset link generation. According to the source code in modules like [`holehe/modules/software/adobe.py`](https://github.com/megadose/holehe/blob/main/holehe/modules/software/adobe.py), the tool only parses the initial HTTP response for "email not found" messages or status codes. It never submits the final request that would cause the service to dispatch a reset email to the target address.

### How does Holehe avoid detection by services?

Holehe implements basic evasion techniques through [`holehe/localuseragent.py`](https://github.com/megadose/holehe/blob/main/holehe/localuseragent.py), which provides randomized User-Agent strings for each request. Additionally, the use of `httpx.AsyncClient` allows for connection pooling and header customization per module. However, the tool does not implement advanced anti-detection measures like proxy rotation or CAPTCHA solving, meaning high-volume checks may trigger rate limiting on some platforms.

### What information does Holehe return besides email existence?

Beyond the boolean `exists` field, Holehe modules return an `emailrecovery` field when services expose masked recovery email addresses (e.g., "t***@gmail.com"), an `others` dictionary containing raw JSON responses from the endpoint, and boolean flags for `rateLimit` and `error` states. The output format in [`holehe/core.py`](https://github.com/megadose/holehe/blob/main/holehe/core.py) aggregates these into a structured report showing exactly which services harbor accounts for the queried address.

### Is it legal to use Holehe for email verification?

The legality depends on jurisdiction and use case. Holehe performs only passive checks against public endpoints, similar to manual registration attempts, which generally does not violate computer fraud statutes. However, using the tool to enumerate accounts for phishing target selection, credential stuffing preparation, or stalking violates most platforms' Terms of Service and may constitute harassment or unauthorized access depending on local laws. Always obtain proper authorization before testing email addresses you do not own.