How Holehe's Register API Detection Method Works: Simulating Registration Flows to Find Email Accounts
Holehe's Register API detection method works by simulating a service's registration flow with the target email and analyzing error responses to determine if an account already exists.
Holehe is an open-source OSINT tool by megadose that checks whether an email address is registered across hundreds of services. The Register API detection method is one of its core techniques, used by modules that set method = "register" to identify existing accounts without requiring authentication. This article explains exactly how this detection mechanism works according to the Holehe source code.
How the Register Method Is Identified and Executed
Holehe discovers and executes register-based modules through a dynamic loading system defined in holehe/core.py.
The import_submodules function recursively imports every module under holehe/modules/, making all detection methods available at runtime. The get_functions helper extracts callable detection functions, and launch_module runs them concurrently against the target email.
When a module uses the Register API method, it explicitly declares:
method = "register"
This metadata allows Holehe to categorize results appropriately when rendering output through print_result, which prefixes successful detections with [+] and rate-limits with [x].
The Register Detection Flow: A 4-Step Process
Every Register API module follows the same operational pattern. Here is how it works, using the Instagram implementation in holehe/modules/social_media/instagram.py as the canonical example.
Step 1: Gather Required Tokens or CSRF Data
Services typically protect their registration endpoints with anti-CSRF measures. The module must first fetch a valid session token.
freq = await client.get("https://www.instagram.com/accounts/emailsignup/", headers=headers)
token = freq.text.split('{\\"config\\":{\\"csrf_token\\":\\"')[1].split('\\"')[0]
This extracts the CSRF token from Instagram's email signup page HTML, which is required for subsequent POST requests.
Step 2: Build a Dummy Registration Payload
The module constructs a registration request using the target email and randomized credentials to avoid rejection for invalid data formats.
import random
import string
data = {
'email': email,
'username': ''.join(random.choice(string.ascii_lowercase + string.ascii_digits) for i in range(random.randint(6, 30))),
'first_name': '',
'opt_into_one_tap': 'false'
}
headers["x-csrftoken"] = token
The random username ensures the request appears as a genuine new registration attempt rather than malformed data.
Step 3: POST to the Registration Endpoint
The module submits the payload to the service's account creation validation endpoint.
check = await client.post(
"https://www.instagram.com/api/v1/web/accounts/web_create_ajax/attempt/",
data=data,
headers=headers)
check = check.json()
This endpoint is specifically designed to validate registration fields before final account creation, making it ideal for detection purposes.
Step 4: Analyze the Response for Existence Signals
The module interprets the JSON response to determine account status:
if check["status"] != "fail":
if 'email' in check["errors"] and check["errors"]["email"][0]["code"] == "email_is_taken":
out.append({
"name": "instagram",
"domain": "instagram.com",
"method": "register",
"frequent_rate_limit": False,
"rateLimit": False,
"exists": True,
"emailrecovery": None,
"phoneNumber": None,
"others": None
})
Each service has unique error codes or messages that indicate "email already taken." Instagram uses email_is_taken; other services may use different strings or HTTP status codes.
Response Handling: Three Possible Outcomes
Register API modules categorize results into three states based on server responses:
| Outcome | Condition | Result Flag |
|---|---|---|
| Account exists | Response contains "email taken" error or equivalent | exists: True |
| Account does not exist | Email accepted as available for registration | exists: False |
| Rate limited or error | HTTP 429, connection failure, or unexpected response | rateLimit: True or error: True |
This standardized output format allows holehe/core.py to aggregate and display results consistently across all 100+ supported services.
Other Services Using Register API Detection
The same pattern appears across multiple modules in the Holehe codebase:
- Tumblr (
holehe/modules/social_media/tumblr.py): Posts tohttps://www.tumblr.com/svc/account/registerand checks foremail_takenin the response. - Discord (
holehe/modules/social_media/discord.py): Useshttps://discord.com/api/v9/auth/registerand analyzes validation errors. - Pinterest (
holehe/modules/social_media/pinterest.py): Hits the signup validation endpoint and parses error messages for email conflicts.
Each module hardcodes the specific endpoint URL, required headers, and error string patterns that uniquely identify that service's "email already registered" response.
Running Holehe with Register Detection
Basic usage checks an email against all supported services including Register API methods:
holehe john.doe@example.com
Typical output showing register detection results:
[+] instagram.com # email already registered (register method)
[-] twitter.com # email not found
[x] reddit.com # rate-limited during check
[!] someforum.com Error # request failed
Filter to show only confirmed accounts:
holehe john.doe@example.com --only-used
Export results for further analysis:
holehe john.doe@example.com -C
Summary
- Register API detection in Holehe works by simulating registration attempts and parsing error responses, not by querying public profile APIs.
- Modules set
method = "register"and implement a 4-step flow: token extraction, payload construction, POST submission, and response analysis. - The
holehe/core.pyorchestrator dynamically loads all modules and executes them concurrently vialaunch_module. - Each service requires custom handling for endpoint URLs, CSRF tokens, and unique error message patterns that indicate existing accounts.
- Results are standardized with
exists,rateLimit, anderrorflags for consistent reporting.
Frequently Asked Questions
What makes Register API detection different from other Holehe methods?
Other methods may query public user endpoints, password reset flows, or login pages. Register API detection specifically exploits the registration validation endpoints that services expose to check email availability before allowing account creation. This often reveals account existence even when other endpoints are protected or require authentication.
Can services detect or block Holehe's Register API checks?
Yes. Services may implement rate limiting, require CAPTCHA challenges, or change their endpoint structures. Modules handle this through the rateLimit flag and by rotating user agents. When Instagram or similar services modify their frontend code, token extraction patterns in modules like instagram.py may require updates to maintain functionality.
Why does Holehe use random usernames instead of static values?
Static usernames would cause validation errors for "username taken" rather than isolating the email check. Randomized usernames (6-30 characters of lowercase letters and digits) ensure the registration attempt fails only on email conflicts, providing clean signal for exists determination.
Is Register API detection legal and ethical for security research?
The technique involves sending minimal, non-destructive requests to public endpoints. However, users should respect each service's Terms of Service, implement appropriate rate limiting, and only use Holehe on email addresses they own or have explicit authorization to test. The tool is designed for legitimate OSINT and security research purposes.
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 →