How to Use Holehe to Check Email Availability: CLI and Python Guide
Run holehe <email> to check if an email address is already registered across 120+ online services, or import holehe.core into your Python scripts for programmatic OSINT checks.
Holehe is a Python-based OSINT (Open Source Intelligence) tool maintained by megadose that probes social media platforms, shopping sites, and other online services to determine email availability. This guide explains both command-line and programmatic usage based on the holehe source code, including how to interpret results, filter output, and integrate the tool into your own applications.
Installing Holehe
The fastest way to get started is via PyPI. The tool requires Python 3.6+.
pip3 install holehe
Verify the installation:
holehe --help
CLI Usage: The Quick Email Check
The simplest way to use holehe to check email availability is with a single argument.
holehe test@example.com
Holehe performs the following steps internally, as defined in holehe/core.py:
- Argument parsing — extracts the email from
parser.add_argument("email", ...)at lines 80-84 - Email validation — validates format via
is_emailregex at lines 31-33 - Module discovery — dynamically imports all modules in
holehe.modulesusingimport_submodules(lines 37-48) - Concurrent execution — runs service checks in parallel with trio and
httpx.AsyncClient - Result formatting — displays colored output and optionally exports to CSV
Understanding the Output
Each service returns a result that holehe renders with color-coded symbols:
| Symbol | Meaning | exists value |
|---|---|---|
[+] |
Account found | True |
[-] |
No account | False |
[x] |
Rate limited | varies |
[!] |
Error occurred | varies |
Example output:
[+] instagram
[-] twitter
[x] reddit
[!] error on some-site
The exists flag in the underlying dictionary determines whether the email is registered on that platform.
CLI Options for Better Results
Filter to accounts only:
holehe test@example.com --only-used
Export to CSV for reporting:
holehe test@example.com --csv
These flags are defined in holehe/core.py lines 84-93. Additional useful options include:
| Flag | Purpose |
|---|---|
--no-color |
Disable colored output for piping |
--no-clear |
Preserve terminal history |
-NP / --no-password-recovery |
Skip password-recovery-based checks |
-T / --timeout <seconds> |
Override default 10-second HTTP timeout |
Python API: Programmatic Email Checks
For integration into larger applications, import holehe's core functions directly. This approach gives you full control over result processing.
import trio
import httpx
from holehe.core import import_submodules, get_functions
async def check_email_availability(email: str):
"""Check email registration status across all supported services."""
# Discover all service modules
modules = import_submodules("holehe.modules")
websites = get_functions(modules) # List of async callables
results = []
# Execute all checks concurrently
async with httpx.AsyncClient(timeout=10) as client:
async with trio.open_nursery() as nursery:
for site in websites:
nursery.start_soon(site, email, client, results)
# Process and return structured results
return sorted(results, key=lambda x: x.get("name", ""))
def run_check(email: str):
"""Synchronous wrapper for trio-based async execution."""
return trio.run(check_email_availability, email)
# Example usage
if __name__ == "__main__":
email = "test@example.com"
results = run_check(email)
for r in results:
status = "registered" if r.get("exists") else "available"
print(f"{r['domain']}: {status}")
Each service function follows the signature async def <service>(email, client, out) and appends a dictionary to out with these keys:
exists— Boolean indicating registration statusname— Human-readable service namedomain— Service domainrateLimit— Whether the check was rate-limitedemailrecovery— Recovery email if leakedphoneNumber— Phone number if leaked
Customizing Checks for Specific Services
To check only specific platforms, filter the websites list before execution:
from holehe.core import import_submodules, get_functions
modules = import_submodules("holehe.modules")
all_sites = get_functions(modules)
# Filter to social media only
target_services = {"instagram", "twitter", "reddit", "facebook"}
filtered_sites = [
s for s in all_sites
if s.__name__.lower() in target_services
]
Individual service implementations reside in holehe/modules/<category>/<service>.py — for example, holehe/modules/social_media/instagram.py.
Timeout and Performance Tuning
The default 10-second timeout per HTTP request can be adjusted via CLI or programmatically:
CLI:
holehe test@example.com -T 30
Python:
async with httpx.AsyncClient(timeout=30) as client:
# ... execute checks
Concurrent execution via trio's nursery pattern means all 120+ services complete in roughly the time of the slowest response, not the sum of all requests.
Summary
- Install holehe with
pip3 install holehefor immediate CLI access - Run
holehe <email>to check email availability across 120+ services with colored terminal output - Use
--only-usedto see registered accounts only,--csvto export results - Import
holehe.corefor programmatic access withimport_submodules(),get_functions(), and trio-based async execution - Check the
existsflag in result dictionaries to determine registration status - Adjust timeout with
-Twhen targeting slow services or working with unreliable connections
Frequently Asked Questions
What does the [+] symbol mean in holehe output?
The [+] symbol indicates exists: True — meaning the email address is already registered on that service. Conversely, [-] means no account was found. The symbols are rendered by the CLI at holehe/core.py lines 46-52 based on each module's returned dictionary.
Can I use holehe without installing the CLI tool?
Yes. Install the package, then import from holehe.core import import_submodules, get_functions to run checks entirely within Python. This is useful for building custom OSINT pipelines or integrating email availability checks into larger applications.
How does holehe check so many services simultaneously?
Holehe uses trio for structured concurrency and httpx.AsyncClient for async HTTP requests. As shown in holehe/core.py lines 13-23, all service functions launch concurrently in a trio.open_nursery() block, sharing a single HTTP client with configurable timeout.
Why do some services show [x] or [!] instead of [+] or [-]?
[x] means the service rate-limited your request (rateLimit: True in the result dict). [!] indicates an unexpected error during the check. Neither confirms nor denies email registration — you may need to retry with different IP addressing or adjust the timeout.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →