A GitHub account registration toolkit that uses Camoufox for browser automation and Litensi for verification mailboxes. It can be run from the CLI or through a local web console.
Use this only for accounts and workflows you are authorized to manage. Automated account registration may violate GitHub's Terms of Service and can result in account or IP restrictions.
- Creates a mailbox, password, and username for GitHub signup.
- Verifies the eight-digit GitHub launch code from Litensi Mail.
- Logs in again when a newly verified account is redirected to
/login. - Optionally creates a first repository, enables TOTP 2FA, and stores recovery codes per account.
- Optionally sets a profile status and completes profile fields after 2FA.
- Provides a web console for configuration, job control, live logs, account export, TOTP generation, and recovery-code viewing.
- Python 3.11 or newer.
- Node.js 18 or newer, only to rebuild the frontend.
- A Litensi account with API credentials and a balance.
- Internet access. A residential proxy may be needed depending on your network.
git clone <repository-url> github-regkit
cd github-regkit
python3 -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip
pip install -r requirements.txt
# Download Camoufox once.
python -m camoufox fetch
# Create local configuration.
cp config.example.json config.jsonOn Windows PowerShell:
.venv\Scripts\Activate.ps1Headful mode (headless: false) needs a display plus the Firefox system
libraries. On a desktop these are usually already installed; on a minimal
server install them and run inside a virtual display:
# Ubuntu 22.04
sudo apt update
sudo apt install -y libgtk-3-0 libdbus-glib-1-2 libxt6 libasound2 xvfb
# Ubuntu 24.04 uses libasound2t64 instead of libasound2
sudo apt install -y libgtk-3-0 libdbus-glib-1-2 libxt6 libasound2t64 xvfb
# headless VPS — wrap headful runs with a virtual display
xvfb-run -a python main.py --count 1For unattended servers, headless: true (or python main.py --headless)
works without a display, though it is slightly more likely to be flagged by
DataDome.
Set your local values in config.json. This file must never be committed.
{
"mail_provider": "mailcx",
"mailcx_domain": "",
"litensi_api_id": "1234",
"litensi_api_key": "your-api-key",
"litensi_site": "github.com",
"litensi_zone": "",
"register_count": 1,
"proxy": "",
"proxy_file": "",
"headless": false,
"delay_sec": 5.0,
"max_username_tries": 6,
"otp_timeout_sec": 240,
"browser_profile_dir": ".browser-profile",
"fresh_profile": true,
"proxy_hard_block_retries": 2,
"proxy_rate_limit_retries": 2,
"create_repo": true,
"repo_name": "hello",
"enable_2fa": true,
"set_profile_status": true,
"profile_status": "On vacation",
"complete_profile": true,
"profile_name": "",
"profile_bio": "",
"profile_location": ""
}| Field | Description |
|---|---|
mail_provider |
Mail backend: mailcx (free, default) or litensi (paid, more reliable). |
mailcx_domain |
Mail.cx domain. Leave blank to auto-pick from available domains. |
litensi_api_id / litensi_api_key |
Litensi API credentials (used when mail_provider is litensi). |
litensi_site |
Sender domain in Litensi, for example github.com. |
litensi_zone |
Mailbox zone. Leave blank to choose the cheapest in-stock zone. |
register_count |
Accounts to process in one job. |
proxy |
Optional single proxy in http://user:pass@host:port format. |
proxy_file |
Optional proxy pool file in the project root (one scheme://user:pass@host:port per line). Each account picks a random proxy; also settable via the web console upload. Takes precedence over proxy. |
headless |
Runs without a browser window. false is easier to observe and often more stable. |
delay_sec |
Delay between accounts. |
max_username_tries |
Username conflict retry limit. |
otp_timeout_sec |
Maximum wait time for the verification email. |
fresh_profile |
Uses a fresh browser profile for each account while carrying trusted cookies separately. |
create_repo / repo_name |
Enables and names the first repository. |
enable_2fa |
Enables TOTP 2FA and captures recovery codes. |
set_profile_status / profile_status |
Enables and sets a post-2FA profile status. |
complete_profile |
Enables post-2FA profile completion. |
profile_name, profile_bio, profile_location |
Custom profile values. Blank fields use Random User or ZenQuotes data. |
Build the UI after frontend changes:
cd frontend
npm install
npm run build
cd ..Start the local server:
source .venv/bin/activate
python -m web.serverOpen http://127.0.0.1:8093.
- Status: start or stop jobs and inspect progress.
- Live Log: review events in real time.
- Config: edit local settings and check Litensi zones.
- Accounts: export accounts, copy values, generate TOTP codes, and view recovery codes.
Protect the web console with a password when needed:
export GITHUB_REGISTER_ACCESS_PASSWORD='use-a-strong-password'
python -m web.serverThe server binds to 127.0.0.1 by default. Do not expose it publicly without
authentication and secure transport.
source .venv/bin/activate
python main.py
python main.py --count 3
python main.py --proxy http://user:pass@host:port
python main.py --headless
python main.py --config config.local.json --count 1Press Ctrl+C to stop the CLI or server. A KeyboardInterrupt or
asyncio.CancelledError during Uvicorn shutdown is expected after interruption.
- Create a Litensi mailbox. An in-stock zone is selected automatically when
litensi_zoneis blank. - Open GitHub signup and fill email, password, and a username based on the mailbox local part.
- Submit the form. If an overlay intercepts pointer clicks, the runner falls back to a DOM click. A disabled form is refreshed and filled with the same data before switching browser sessions.
- Poll the Litensi mailbox and enter the GitHub launch code.
- Sign in again if GitHub redirects the new account to login.
- Create the first repository when enabled.
- Enable TOTP 2FA, capture recovery codes, and persist them per account.
- Optionally set profile status, then complete profile name, bio, and location.
Post-signup stage failures do not discard an account that was already verified. The reason is written to Live Log.
accounts/
github_accounts_<timestamp>.txt
recovery/
<email-hash>.txt
Each account file contains one line per account:
email----password----username----totp_secret----has_recovery
Recovery codes are stored separately under accounts/recovery/. The Accounts
page can reveal and copy them with the Recovery action.
Example account output:
user@example.com----example-password----example-user----EXAMPLETOTPSECRET000
Generate a TOTP code manually from the fourth field:
python -c "import pyotp; print(pyotp.TOTP('EXAMPLETOTPSECRET000').now())"record_camoufox.py opens Camoufox and records clicks, inputs, and navigation.
.venv/bin/python record_camoufox.py
.venv/bin/python record_camoufox.py --url https://github.com/loginIts output can contain email addresses, session URLs, and selectors. Treat
recorded_steps.json as sensitive local data.
| Problem | Action |
|---|---|
BAD SITE |
Use a complete domain such as github.com for litensi_site. |
| No zone or stock | Use Check Zone, choose an in-stock zone, or leave it blank for automatic selection. |
| No verification email | Check Litensi balance and allow the mailbox reorder retry. |
| DataDome hard block or signup 403 | Change IP/proxy, disable VPN/WARP, then retry after a delay. |
| Create account or repository will not click | Review Live Log. Native clicks fall back to DOM clicks when an overlay intercepts them. |
| Web UI does not reflect frontend changes | Run npm run build, then restart python -m web.server. |
- Never commit
config.json,accounts/,.browser-profile/,.datadome-trust.json, recovery codes, or browser recordings. - Account files contain full credentials, including password and TOTP secret.
- Recovery codes grant account recovery and should be stored securely.
- Before pushing, inspect
git status --shortandgit diff --cached.
Released under the MIT License.
