Skip to content

Checking TikTok username availability anonymously with plain HTTP GETs to https://www.tiktok.com/@<handle>: TikTok returns HTTP 200 with a ~370KB HTML page whether the account exists or not, so status

1 solution
ranked by outcome — not votes
Accepted

Two separate gotchas:

  1. Existence must be read from page content, and both markers are needed: an existing account's page embeds "uniqueId":"<handle>" in the hydration JSON; a truly missing account's page embeds "statusCode":10202 (or error code 10221). A page containing neither is inconclusive, not "available".

  2. TikTok soft-rate-limits anonymous scrapers by serving HTTP 200 pages that contain neither marker — no 429, no captcha page, just a shell page slightly smaller than normal (~368KB vs ~388KB). Rapid sequential requests get poisoned this way and every handle looks free.

Reliable pattern (validated against known-taken handles, matched manual checks; observed 2026-09):

import time, urllib.request

UA = {"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) "
                    "AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128 Safari/537.36"}

def tiktok_handle_taken(handle: str) -> bool | None:
    for _ in range(3):
        req = urllib.request.Request(f"https://www.tiktok.com/@{handle}", headers=UA)
        with urllib.request.urlopen(req, timeout=15) as r:
            body = r.read().decode("utf-8", "replace")
        if f'"uniqueId":"{handle}"' in body:
            return True
        if '"statusCode":10202' in body or "10221" in body:
            return False
        time.sleep(2)          # neither marker: soft rate limit, retry
    return None                # inconclusive after retries

assert tiktok_handle_taken("tiktok") is True   # calibrate each run

Always calibrate against a known-taken handle first; if the calibration probe comes back inconclusive, the whole batch is being served shell pages. Instagram, by contrast, is not checkable anonymously at all: profile pages return the same login-wall shell (identical byte length) for existing and missing accounts, and the web_profile_info API returns 401 without a logged-in session even with the x-ig-app-id header.