Holehe Instagram Email Checking Logic: How It Simulates Sign-Up Flow
Holehe verifies whether an email is registered on Instagram by simulating the platform's sign-up flow, extracting CSRF tokens from the public signup page, submitting fake registration payloads to an internal AJAX endpoint, and parsing JSON error responses for specific patterns like "email_is_taken" or "email_sharing_limit".
The open-source OSINT tool Holehe checks email registration status across hundreds of services by exploiting public account creation endpoints. In the megadose/holehe repository, the Instagram module implements a sophisticated email existence verification that mimics legitimate user registration attempts without creating actual accounts. This approach leverages Instagram's own validation infrastructure to leak account existence information through error messages.
Overview of the Instagram Email Verification Flow
The Instagram email checking logic operates by exploiting Instagram's web-based account creation API. Rather than using public profile lookup endpoints—which often require authentication—the module submits incomplete registration attempts to trigger validation errors that expose whether an email is already in use.
This method avoids authentication barriers while providing reliable boolean results for email existence, rate-limit detection, and error handling through a standardized output schema.
Step-by-Step Implementation in holehe/modules/social_media/instagram.py
The core logic resides in holehe/modules/social_media/instagram.py, where the primary function orchestrates a four-phase verification process using asynchronous HTTP requests.
Fetching the CSRF Token
First, Holehe establishes a session and extracts the required anti-forgery token. The module sends a GET request to /accounts/emailsignup/ and parses the HTML response to retrieve the hidden CSRF token embedded in the page's form fields.
This token extraction occurs at lines 21-23 of instagram.py. The code isolates the csrf_token value necessary for subsequent POST requests, storing it for the validation phase.
Constructing the Registration Payload
Next, the module prepares a payload designed to trigger email validation without completing registration. The code generates a random username and sets an empty first name while inserting the target email verbatim into the POST body.
As implemented at lines 31-37, this payload includes:
email: The target address being checkedusername: A randomly generated string to avoid conflictsfirst_name: An empty stringopt_into_one_tap: Set tofalse
Submitting to the Internal AJAX Endpoint
With the CSRF token and payload ready, Holehe submits the request to Instagram's internal validation endpoint. The POST request targets /api/v1/web/accounts/web_create_ajax/attempt/ with the CSRF token included in the x-csrftoken header.
Lines 38-42 handle this submission, using the asynchronous HTTP client from holehe/core.py to send the request with appropriate headers and cookie contexts established during the initial token fetch.
Parsing the JSON Response
The response interpretation logic determines whether the email exists based on specific error patterns. If the response status is not "fail", the code inspects check["errors"]["email"] for two specific indicators:
"email_is_taken": The error code confirming the email is already registered"email_sharing_limit": A secondary string pattern indicating the email has reached usage limits
Lines 44-58 implement this check, returning exists = True when either pattern appears. If these error patterns are absent, lines 60-66 set exists = False, indicating the email is available for registration.
Handling Rate Limits and Edge Cases
When Instagram returns a response with status "fail", the module assumes rate-limiting has been applied. Lines 67-73 catch this condition, setting rateLimit = True and exists = None to indicate the check could not complete due to throttling.
All results append to the shared out list as structured dictionaries containing:
name:"instagram"domain:"instagram.com"method:"register"exists: Boolean or NonerateLimit: Boolean indicating throttling statusfrequent_rate_limit: Predefined service-specific flagemailrecovery,phoneNumber,others: Additional metadata fields (typically None for this module)
Practical Implementation Example
To check an email programmatically using Holehe's Instagram module:
import asyncio
from holehe import core
from holehe.modules.social_media import instagram
async def check_instagram(email):
async with core.Client() as client:
out = []
await instagram.instagram(email, client, out)
return out[0]
result = asyncio.run(check_instagram("test@example.com"))
print(result)
This returns a standardized dictionary detailing the verification outcome, including existence status and rate-limit detection.
Summary
- Holehe's Instagram module exploits the
/api/v1/web/accounts/web_create_ajax/attempt/endpoint to verify email registration status without completing account creation. - The implementation requires CSRF token extraction from
/accounts/emailsignup/before submitting fake registration payloads with randomized usernames. - Email existence is determined by parsing error codes
"email_is_taken"or strings containing"email_sharing_limit"in the JSON response at lines 44-58. - Rate limiting detection occurs when the response status equals
"fail", triggering therateLimit = Trueflag at lines 67-73. - All results follow the standardized schema defined in
holehe/modules/social_media/instagram.py, enabling consistent integration with Holehe's broader OSINT framework.
Frequently Asked Questions
What specific error codes indicate an email is already registered on Instagram?
Instagram's API returns "email_is_taken" in the error object when an email is already associated with an existing account. Additionally, Holehe checks for the substring "email_sharing_limit", which appears when an email has reached the maximum number of allowed registrations. Both patterns trigger the exists = True result in the output dictionary.
How does Holehe avoid detection when checking multiple emails?
The module randomizes usernames for each request and relies on the core.Client class from holehe/core.py, which manages sessions and retries. However, aggressive usage still triggers Instagram's rate-limiting protections, which the module detects via the "fail" status code and reports through the rateLimit field.
Can this method detect if an email has account recovery options enabled?
No. The current implementation in holehe/modules/social_media/instagram.py focuses exclusively on existence detection via the registration endpoint. While the output schema reserves fields for emailrecovery and phoneNumber, the Instagram module populates these with None as the AJAX endpoint used does not return account recovery metadata.
What happens when Instagram returns an unexpected response format?
If the JSON response lacks the expected error structure or contains a "fail" status unrelated to rate-limiting, the module conservatively sets exists = False while allowing the exception to propagate. The error handling at lines 60-73 ensures the tool continues functioning even when Instagram modifies their API responses, preventing false positives.
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 →