Skip to content

Commit 979ae81

Browse files
authored
fix(instagram): replace broken web_profile_info endpoint with signup-attempt check (#328)
The web_profile_info API now returns 401 for all unauthenticated requests, breaking Instagram username scanning entirely. Switch to the signup-attempt endpoint (web_create_ajax/attempt) which reliably indicates username availability without requiring authentication. Co-authored-by: Matt Kneale <matt@drmk.link>
1 parent ca01997 commit 979ae81

1 file changed

Lines changed: 33 additions & 21 deletions

File tree

Lines changed: 33 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,46 @@
1+
import httpx
2+
13
from user_scanner.core.helpers import get_random_user_agent
2-
from user_scanner.core.orchestrator import status_validate
4+
from user_scanner.core.orchestrator import generic_validate
5+
from user_scanner.core.result import Result
36

47

58
def validate_instagram(user):
6-
url = "https://www.instagram.com/api/v1/users/web_profile_info/"
79
show_url = f"https://www.instagram.com/{user}/"
8-
9-
params = {"username": user}
10+
url = "https://www.instagram.com/api/v1/web/accounts/web_create_ajax/attempt/"
1011

1112
headers = {
1213
"User-Agent": get_random_user_agent(),
13-
"Accept-Encoding": "gzip, deflate, br, zstd",
14-
"sec-ch-ua-full-version-list": '"Not(A:Brand";v="8.0.0.0", "Chromium";v="144.0.7559.132", "Google Chrome";v="144.0.7559.132"',
15-
"sec-ch-ua-platform": '"Linux"',
16-
"sec-ch-ua": '"Not(A:Brand";v="8", "Chromium";v="144", "Google Chrome";v="144"',
17-
"sec-ch-ua-model": '""',
18-
"sec-ch-ua-mobile": "?0",
14+
"Accept": "*/*",
1915
"x-ig-app-id": "936619743392459",
16+
"x-csrftoken": "0",
2017
"x-requested-with": "XMLHttpRequest",
21-
"sec-ch-prefers-color-scheme": "dark",
22-
"x-ig-www-claim": "0",
23-
"sec-ch-ua-platform-version": '""',
24-
"sec-fetch-site": "same-origin",
25-
"sec-fetch-mode": "cors",
26-
"sec-fetch-dest": "empty",
27-
"referer": f"https://www.instagram.com/{user}",
28-
"accept-language": "en-US,en;q=0.9",
29-
"priority": "u=1, i",
18+
"referer": "https://www.instagram.com/accounts/emailsignup/",
19+
"content-type": "application/x-www-form-urlencoded",
20+
"cookie": "csrftoken=0",
3021
}
3122

32-
return status_validate(
33-
url, 404, 200, show_url=show_url, params=params, headers=headers, http2=True
23+
def check_response(response: httpx.Response) -> Result:
24+
try:
25+
data = response.json()
26+
except Exception:
27+
return Result.error(f"[{response.status_code}] Unexpected response from Instagram.")
28+
29+
errors = data.get("errors", {})
30+
username_errors = errors.get("username", [])
31+
32+
for err in username_errors:
33+
if err.get("code") in ("username_invalid", "username_is_taken"):
34+
return Result.taken()
35+
36+
return Result.available()
37+
38+
return generic_validate(
39+
url,
40+
check_response,
41+
show_url=show_url,
42+
headers=headers,
43+
data={"username": user, "email": "", "first_name": "", "opt_into_one_tap": "false"},
44+
method="POST",
45+
http2=True,
3446
)

0 commit comments

Comments
 (0)