Discover, check, and track availability of short usernames across platforms — starting with Instagram 3-character handles, architected to add more platforms later.
Short handles are scarce and their availability changes over time as accounts are deleted or released. This tool treats checking as a recurring, observable activity: generate or curate candidate handles, probe them against a real browser session, and persist the results so you can see what changed.
- Generates candidate handles from character-class rules, excluding known-taken handles.
- Checks availability by driving a real Chromium browser session (Playwright) against Instagram.
- Persists results in a small SQLite store, tracking each handle's status, confidence, timestamp, and evidence.
- Reports on the latest known status of every tracked handle.
The Instagram probe only observes — it navigates to a handle's profile page and classifies what it sees. It does not attempt to sign up for or claim handles.
Screenshot placeholder — add your own screenshot to assets/screenshot.png
short-handle-discovery/
├── cli.py # Entrypoint: shd check | report | generate | session:start | session:status
├── pyproject.toml
├── requirements.txt
├── LICENSE # MIT
├── README.md
├── .gitignore
├── candidates/
│ ├── generators/
│ │ └── gen3.py # 3-character handle generator with blacklist support
│ └── lists/
│ ├── candidates.txt # 439 curated candidate handles
│ ├── unknown.txt # handles whose status is still unknown
│ ├── taken.txt # (optional) confirmed-taken blacklist
│ ├── available.txt # (optional) confirmed-available watchlist
│ └── readme.md
├── probes/
│ ├── base.py # Probe interface and shared helpers
│ └── instagram.py # Instagram availability probe
├── session/
│ ├── manager.py # Chromium session lifecycle and login detection
│ ├── events.py # Session lifecycle events
│ └── profile/ # Chromium user profile — gitignored, treated as a secret
└── state/
├── models.py # Handle, CheckResult, CheckRecord
└── store.py # SQLite-backed persistence
Install dependencies and the Chromium browser that Playwright drives:
pip install -r requirements.txt
playwright install chromiumThe session/profile/ directory is a Chromium user profile. It is gitignored because it contains login state — cookies, local storage, and saved logins. Treat it like credentials:
- Do not commit it.
- Do not share it.
- Do not push it to a public repository.
To use the tool, you need a profile that is logged into Instagram. If you don't have one yet, see Logging in.
Check the handles in unknown.txt (10 handles):
python cli.py checkCheck specific handles:
python cli.py check abc def 123Check every handle in candidates.txt (439 handles):
python cli.py check --allSkip handles that already have a known status (resume):
python cli.py check --resumeLimit how many handles to check in one run:
python cli.py check --all --limit 20Write results to JSON:
python cli.py check --output results.jsonRead handles from a custom list file:
python cli.py check --list my_handles.txtShow the latest known status of tracked handles:
python cli.py reportFilter by status:
python cli.py report --status available
python cli.py report --status taken
python cli.py report --status unverifiedLimit results:
python cli.py report --limit 20Write a report to JSON:
python cli.py report --output report.jsonGenerate candidate 3-character handles, excluding known-taken ones from taken.txt and from the store:
python cli.py generate --count 50Generate and save to a file:
python cli.py generate --count 200 --output new_candidates.txtInspect the profile (does not confirm login state):
python cli.py session:statusStart an interactive session and leave it open:
python cli.py session:startStart headed (required for some profiles, and for logging in):
python cli.py session:start --headedThe tool needs a Chromium profile that is logged into Instagram. The included session/profile/ is a cloned profile that is not currently logged in — running checks with it will report LOGIN_REQUIRED.
To set up a logged-in profile:
- Run
python cli.py session:start --headed— this launches a Chromium window using the profile. - Log in to Instagram manually in that window.
- Stop the session (Ctrl+C).
- Run
python cli.py checkto verify the session is working.
If Instagram flags or logs out the profile later, repeat the login step. Instagram actively fights automation, so session health can degrade over time.
For each handle, the probe:
- Navigates to
https://www.instagram.com/<handle>/. - Waits for the page to load.
- Classifies the page:
- LOGIN_REQUIRED — a login wall was detected.
- AVAILABLE (low confidence) — the page uses "unavailable" phrasing.
- TAKEN (high/medium confidence) — profile UI elements were detected.
- UNVERIFIED (low confidence) — the page was unclear; evidence is captured so you can confirm later.
- Records the result with timestamp, confidence, session id, and evidence.
Results are best-effort. Instagram's pages and anti-automation behavior change, so treat output as data to act on rather than ground truth.
The candidates/lists/ directory holds curated handle lists, one handle per line, lowercase:
| File | Purpose |
|---|---|
candidates.txt |
Main candidate list to check. |
unknown.txt |
Handles whose status is still unknown — the default target for check. |
taken.txt |
Confirmed-taken handles; used as a blacklist by the generator. |
available.txt |
Confirmed-available handles; a watchlist for re-checking. |
You can edit these files directly, or use shd generate to produce new candidates.
The tool is split into three concerns so each can evolve independently:
- Candidates — where handles come from (lists or generators).
- Probes — how availability is checked (one module per platform).
- State — what we know about each handle (persisted results).
The session layer sits underneath the probes: it manages the browser profile and detects when login state is lost. A probe should never assume the session is healthy — it checks and reports honestly.
Adding a new platform means adding a new probe module that implements the same interface. The Instagram probe is the reference implementation.
- Instagram aggressively fights automation. Rate limits, captchas, and session flagging are expected. The tool reports these honestly rather than hiding them.
- Classification is heuristic and best-effort. Low-confidence results should be manually verified.
- The Chromium profile is a sensitive asset. Keep it private and be prepared to refresh it when Instagram invalidates it.
- This is a personal/research tool. It is not affiliated with Instagram and is not a service for claiming handles on your behalf.
MIT — see LICENSE.
- Built with Playwright for browser automation
- Uses SQLite for lightweight, reliable persistence
- Follows Keep a Changelog format
- Contributing guidelines based on Contributor Covenant
