# How Holehe Detects If an Email Is Registered on a Website: A Technical Deep Dive

> Learn how Holehe detects email registration on websites. Discover its technical approach using service-specific modules and public APIs to check email existence.

- Repository: [Palenath/holehe](https://github.com/megadose/holehe)
- Tags: deep-dive
- Published: 2026-08-28

---

**Holehe detects email registration by executing service-specific asynchronous modules that query public APIs, password-reset endpoints, or registration forms to determine if an address exists on a target platform.**

Holehe is an open-source OSINT tool developed by megadose that programmatically checks whether an email address is registered across thousands of online services. Unlike simple web scraping tools, Holehe employs a **modular, request-driven architecture** that leverages each platform's unique validation endpoints to infer account existence without authentication. The tool orchestrates thousands of concurrent HTTP requests via `aiohttp` to deliver comprehensive results in seconds.

## The Core Architecture in [`holehe/core.py`](https://github.com/megadose/holehe/blob/main/holehe/core.py)

The detection workflow begins in [`holehe/core.py`](https://github.com/megadose/holehe/blob/main/holehe/core.py), which serves as the main orchestrator. This module initializes a shared `aiohttp.ClientSession` and dynamically loads every asynchronous function exported by the Python modules located under `holehe/modules/*`.

The core executes these functions concurrently using `asyncio`, passing three critical parameters to each module:
- The target **email address** string
- The shared **HTTP client** instance
- A **result collector** object for appending outcomes

This design allows Holehe to query hundreds of services simultaneously while maintaining a single connection pool. The `run_holehe` function (exposed in [`core.py`](https://github.com/megadose/holehe/blob/main/core.py)) serves as the primary entry point for programmatic usage, returning a standardized list of `(service, status)` tuples.

## Detection Strategies Employed by Holehe Modules

Each module in `holehe/modules/` implements a tailored detection strategy specific to that platform's infrastructure. These strategies fall into four distinct categories based on the target service's available endpoints.

### Public "Email-Available" APIs

Many modern platforms expose lightweight JSON endpoints specifically designed to check username or email availability during registration. Holehe exploits these public APIs to definitively determine registration status.

- **Google**: The module sends a `POST` request to `https://accounts.google.com/_/signup/webusernameavailability` and inspects the JSON response for a `"taken"` flag, as implemented in [`holehe/modules/mails/google.py`](https://github.com/megadose/holehe/blob/main/holehe/modules/mails/google.py).
- **GitHub**: The function posts to `https://github.com/signup_check/email` and parses the `"email"` field in the response to determine if the address is already associated with an account.
- **Replit**: The module queries `https://replit.com/data/user/exists` with the email in the request body and interprets the boolean `exists` value returned by the server.

### Password-Reset and Login-Check Endpoints

When direct availability APIs are absent, Holehe simulates a **password-reset request** and analyzes the server's response to infer account existence.

- **Yahoo**: The module posts to Yahoo's password-reset service endpoint and examines the returned HTML for specific "not found" or "account doesn't exist" message strings, located in [`holehe/modules/mails/yahoo.py`](https://github.com/megadose/holehe/blob/main/holehe/modules/mails/yahoo.py).

This technique relies on subtle differences in error messages: valid accounts typically receive a "password reset link sent" confirmation, while non-existent addresses trigger distinct error responses.

### Form Validation via POST Requests

Legacy platforms and social media sites often expose internal registration validation endpoints that return structured data when forms are submitted via `XMLHttpRequest`.

- **Instagram**: The module sends a `POST` request to an internal validation URL (`/api/v1/web/accounts/web_create_ajax/attempt/`) and checks the JSON response for an `exists` flag indicating the email is already registered, as seen in [`holehe/modules/social_media/instagram.py`](https://github.com/megadose/holehe/blob/main/holehe/modules/social_media/instagram.py).
- **Forum Software**: Platforms using legacy forum software expose [`xmlhttp.php`](https://github.com/megadose/holehe/blob/main/xmlhttp.php) endpoints that return `0` or `1` values indicating email availability, which modules parse to determine registration status.

### HTML Scraping and CSRF Token Extraction

For platforms without programmatic APIs, Holehe modules perform **full browser simulation** by:
1. Fetching the registration page to extract hidden CSRF tokens and cookies
2. Submitting the registration form with the target email address
3. Parsing the resulting HTML for strings like "already registered," "email taken," or specific error divs

This method requires maintaining session state and handling JavaScript-rendered forms, making it the most fragile but necessary approach for older web applications.

## How Results Are Interpreted and Aggregated

After each module executes its detection logic, it categorizes the outcome into one of three states before appending to the shared output object:

- **Registered**: The service confirmed the email exists (HTTP 200 with positive indicator)
- **Available**: The service explicitly indicated the email is not registered
- **Unknown**: The request failed, was rate-limited, or returned ambiguous data

The orchestrator in [`core.py`](https://github.com/megadose/holehe/blob/main/core.py) aggregates these individual results into a tidy table for CLI output or a Python list when used programmatically. The [`holehe/instruments.py`](https://github.com/megadose/holehe/blob/main/holehe/instruments.py) file defines a custom Trio progress instrument that tracks concurrent execution status during large batch operations.

## Using Holehe to Check Email Registration

### Command-Line Interface

Holehe exposes a simple CLI for immediate OSINT investigations:

```bash

# Check a single address across all supported services

holehe example@domain.com

# Limit detection to specific platforms

holehe -l google,github,instagram example@domain.com

```

The `-l` flag filters the loaded modules, reducing execution time and network footprint when targeting specific service categories.

### Programmatic API

Developers can integrate Holehe directly into Python applications using the `run_holehe` async function:

```python
import asyncio
from holehe.core import run_holehe

async def check_email_registration():
    results = await run_holehe(
        email="example@domain.com",
        modules=["google", "github", "instagram"]  # Optional filter

    )
    
    for service, status in results:
        print(f"{service}: {status}")

asyncio.run(check_email_registration())

```

This returns a list of tuples containing the service name and detection status, enabling automated processing of registration data across multiple domains.

## Summary

- **Holehe** detects email registration through **service-specific modules** located in `holehe/modules/` that implement unique detection strategies for each platform.
- Detection methods include **public availability APIs** (Google, GitHub), **password-reset analysis** (Yahoo), **form validation endpoints** (Instagram), and **HTML scraping** for legacy sites.
- The **orchestrator** in [`holehe/core.py`](https://github.com/megadose/holehe/blob/main/holehe/core.py) manages concurrent `aiohttp` requests via `asyncio`, executing all modules simultaneously for rapid results.
- Results are categorized as **registered**, **available**, or **unknown** based on HTTP responses, JSON fields, or HTML parsing.
- The tool supports both **CLI usage** and **programmatic integration** via the `run_holehe` async function.

## Frequently Asked Questions

### What is Holehe and how does it work?

Holehe is an asynchronous Python tool that checks if an email address is registered on thousands of websites. It works by running specialized modules—located in `holehe/modules/`—that query each platform's signup, password-reset, or validation endpoints to determine account existence without requiring authentication.

### Is using Holehe to check email registration legal?

Holehe operates by sending the same HTTP requests a standard web browser would send during user registration or password recovery. However, users must comply with the **Terms of Service** of target platforms and applicable local laws regarding automated data collection. The tool is intended for legitimate security research and personal account auditing only.

### How accurate is Holehe's detection?

Accuracy depends on the target platform's API stability. Services with **public availability endpoints** (like GitHub or Google) yield near-perfect accuracy, while **HTML scraping** methods may produce false negatives if a site updates its markup. The `unknown` status is returned when rate limiting or API changes prevent definitive determination.

### Can I add custom modules to Holehe?

Yes. Holehe's modular architecture allows developers to create custom detection modules by implementing async functions that accept an email string, `aiohttp` client, and result collector. New modules should be placed in the appropriate subdirectory under `holehe/modules/` and will be automatically loaded by the core orchestrator at runtime.