# Holehe Standard Module Output Format: Schema and Structure Explained

> Understand the Holehe standard module output format. Learn the schema and structure including keys like exists rateLimit emailrecovery and domain for uniform results.

- Repository: [Palenath/holehe](https://github.com/megadose/holehe)
- Tags: api-reference
- Published: 2026-08-25

---

**Holehe modules return a standardized ten-field dictionary containing keys such as `exists`, `rateLimit`, `emailrecovery`, and `domain`, enabling the core engine in [`holehe/core.py`](https://github.com/megadose/holehe/blob/main/holehe/core.py) to aggregate and display results uniformly across all services.**

Holehe is an open-source email investigation framework developed by megadose that asynchronously queries over 120 websites to determine if an email address is registered. According to the megadose/holehe source code, every service-specific module adheres to a strict **standard module output format** that returns a predictable dictionary schema. This unified structure allows the CLI and downstream automation tools to process results from any module without custom parsing logic.

## Standard Output Schema Definition

Each module must return a dictionary containing the following ten standardized fields as documented in the README and enforced by `print_result` in [`holehe/core.py`](https://github.com/megadose/holehe/blob/main/holehe/core.py) (lines 22‑48):

- **name** (`str`): Internal module identifier (e.g., `snapchat`).
- **domain** (`str`): Primary domain of the service (e.g., `snapchat.com`).
- **method** (`str`): The authentication vector checked (`login`, `register`, `password recovery`, etc.).
- **frequent_rate_limit** (`bool`): Flag indicating if the service commonly imposes rate limits.
- **rateLimit** (`bool`): `True` if the current request was rate-limited, otherwise `False`.
- **exists** (`bool`): `True` if an account exists for the supplied email on the target service.
- **emailrecovery** (`str | None`): Partially obfuscated recovery email address, if revealed by the service.
- **phoneNumber** (`str | None`): Partially obfuscated recovery phone number, if available.
- **others** (`dict | None`): Additional metadata such as full name or account creation date.
- **error** (`bool`, optional): Present only when an unexpected exception occurs during execution.

## How the Core Engine Processes Module Output

The architectural flow that enforces this schema operates in three stages within the megadose/holehe codebase.

**Module Execution Stage**: Individual modules (e.g., `holehe.modules.social_media.snapchat`) perform asynchronous HTTP requests using `httpx`, parse the response, and construct a dictionary matching the exact schema above. In [`holehe/modules/social_media/snapchat.py`](https://github.com/megadose/holehe/blob/main/holehe/modules/social_media/snapchat.py) (lines 31‑38), the module explicitly assigns values to each required key before returning.

**Aggregation Stage**: The core runner (`launch_module` in [`holehe/core.py`](https://github.com/megadose/holehe/blob/main/holehe/core.py)) catches any exceptions during module execution. If an error occurs, it injects an `"error": True` entry into the output and populates default values for the remaining fields to maintain schema consistency.

**Presentation Stage**: All module dictionaries are collected into a list named `out`, sorted, and passed to `print_result`. This function interprets the standardized fields—specifically `rateLimit`, `exists`, and `others`—to generate the colored CLI output, ensuring uniform formatting regardless of which service was queried.

## Implementing the Format in Module Code

Service modules instantiate the standard dictionary directly in their return statements. The following pattern from [`snapchat.py`](https://github.com/megadose/holehe/blob/main/snapchat.py) demonstrates the implementation:

```python

# From holehe/modules/social_media/snapchat.py (lines 31-38)

return {
    "name": "snapchat",
    "domain": "snapchat.com",
    "method": "register",
    "frequent_rate_limit": False,
    "rateLimit": False,
    "exists": True,
    "emailrecovery": None,
    "phoneNumber": None,
    "others": {}
}

```

This explicit construction ensures that `print_result` in [`holehe/core.py`](https://github.com/megadose/holehe/blob/main/holehe/core.py) receives data in the expected structure, allowing the CLI to render results without additional transformation logic.

## Working with Module Output Programmatically

You can interact with the standard module output format directly through Python to build custom workflows or integrate Holehe into larger applications.

### Invoking a Single Module Directly

To retrieve the standardized dictionary from an individual module without running the full CLI:

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

async def check_single_email():
    email = "test@example.com"
    out = []
    async with httpx.AsyncClient() as client:
        await snapchat(email, client, out)
    print(out)
    # Output: [{'name': 'snapchat', 'domain': 'snapchat.com', 'method': 'register', ...}]

trio.run(check_single_email)

```

### Running the Full Engine Programmatically

To execute the complete workflow and receive all module outputs:

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

async def run_full_scan():
    # maincore parses arguments, launches all modules, and prints results

    await maincore()

trio.run(run_full_scan)

```

`maincore` collects every module’s standardized dictionary, sorts the resulting list, and feeds it to `print_result` for terminal display.

### Parsing Results for Automation

Because every entry follows the identical schema, you can safely filter the output list:

```python
def extract_existing_accounts(results):
    """Filter the standardized output for confirmed accounts."""
    return [r for r in results if r.get("exists") is True]

# Example usage with collected results

existing = extract_existing_accounts(out)
for account in existing:
    recovery = account.get("emailrecovery") or account.get("phoneNumber")
    print(f"{account['domain']}: {recovery}")

```

## Summary

- Holehe modules return a **standardized dictionary** with ten specific keys including `exists`, `rateLimit`, and `domain`.
- The schema is enforced by `print_result` in [`holehe/core.py`](https://github.com/megadose/holehe/blob/main/holehe/core.py) and implemented consistently across all modules such as [`snapchat.py`](https://github.com/megadose/holehe/blob/main/snapchat.py).
- The `launch_module` function in the core engine handles exceptions by injecting an `"error"` flag while preserving the standard structure.
- This unified format allows the CLI and external scripts to process results from over 120 services without custom parsers.

## Frequently Asked Questions

### What fields are required in every Holehe module output dictionary?

Every module must return a dictionary containing `name`, `domain`, `method`, `frequent_rate_limit`, `rateLimit`, `exists`, `emailrecovery`, `phoneNumber`, and `others`. The `error` field is optional and only included when an exception occurs. These requirements are documented in the README and enforced by the core printing logic in [`holehe/core.py`](https://github.com/megadose/holehe/blob/main/holehe/core.py).

### How does Holehe indicate rate limiting in the standard output?

Modules set the `rateLimit` boolean to `True` when the service rejects the request due to throttling. Additionally, modules declare `frequent_rate_limit` as `True` during initialization if the service is known for aggressive rate limiting, allowing the CLI to set appropriate user expectations.

### Can I access Holehe module results without using the command-line interface?

Yes. You can import individual modules (e.g., `from holehe.modules.social_media.snapchat import snapchat`) and call them with an `httpx.AsyncClient` and an output list. The module appends the standardized dictionary to your list, which you can then process programmatically without invoking `maincore` or the CLI.

### What happens when a module fails to complete its check?

If a module raises an unexpected exception, the `launch_module` function in [`holehe/core.py`](https://github.com/megadose/holehe/blob/main/holehe/core.py) catches the error and returns a dictionary with the `error` key set to `True`. The remaining fields are populated with default values to maintain schema consistency, ensuring that `print_result` can still process the entry without crashing.