Files
autoreg-skills-max/skills/grok-autoreg/SKILL.md

27 KiB
Raw Blame History

name, description
name description
grok-autoreg Use when registering Grok/x.ai accounts in bulk.

Grok/x.ai Auto-Registration

Trigger

Mass-registering Grok (x.ai) accounts, extracting API tokens, or managing the Grok token pool.

CRITICAL: Search Before Writing

Before writing ANY custom registration script:

  1. Search GitHub for existing solutions — search grok register, grok autoreg, grok2api on GitHub
  2. Search the user's PC for ready-made tools — check ~/Documents/, ~/Desktop/, ~/projects/ for directories like *grok*, *gw*, *gateway*, *2api*
  3. Check if the gw46.py gateway exists at C:\Users\User\Documents\grok46gw/gw46.py — it's a complete Grok API gateway with OAuth auto-registration, device code flow, and SQLite account storage

Existing ready-made tools found on this PC:

  • C:\Users\User\Documents\grok46gw/gw46.py — Grok 4.6 Gateway (FastAPI, OAuth, device code flow, SQLite)
  • C:\Users\User\Desktop\free2api/ — Node.js API gateway (Freemodel/OpenAI proxy)
  • C:\Users\User\Desktop\ready_grok_reg/ — Cloned from ReinerBRO/grok-register (DrissionPage-based, Turnstile shadow DOM bypass)

Existing GitHub repos:

  • ReinerBRO/grok-register (398 ★) — DrissionPage-based, Chrome extension for Turnstile bypass, DuckMail temp emails, auto-push to grok2api
  • xinxinshuhao-create/grok-register (48 ★) — curl_cffi-based, YesCaptcha, multi-provider email support, device flow for token minting

Turnstile Bypass: Shadow DOM Technique (Best Approach Found)

The DrissionPage-based approach (ReinerBRO/grok-register) uses a Chrome extension + shadow DOM access to bypass Turnstile WITHOUT 2captcha:

  1. The Turnstile widget container has a shadow root with an iframe inside
  2. The script accesses the shadow root via element.shadow_root
  3. Finds the iframe and injects JavaScript to patch MouseEvent.screenX/screenY
  4. Clicks the challenge button inside the iframe
  5. The patched mouse event coordinates make Cloudflare's behavioral detection pass
  6. The Turnstile auto-solves without user interaction

This is more reliable than 2captcha — it doesn't depend on external captcha solving services and works on both the code-page Turnstile (sitekey 0x4AAAAAAADnQ4F4U8W2nQyH) and the profile-page Turnstile (sitekey 0x4AAAAAAAhr9JGVDZbrZOo0).

Key code pattern (from DrissionPage_example.py):

challengeSolution = page.ele("@name=cf-turnstile-response")
challengeWrapper = challengeSolution.parent()
challengeIframe = challengeWrapper.shadow_root.ele("tag:iframe")
challengeIframe.run_js("""
    // Patch MouseEvent to bypass Cloudflare behavioral detection
    Object.defineProperty(MouseEvent.prototype, 'screenX', { value: screenX });
    Object.defineProperty(MouseEvent.prototype, 'screenY', { value: screenY });
""")
challengeIframeBody = challengeIframe.ele("tag:body").shadow_root
challengeButton = challengeIframeBody.ele("tag:input")
challengeButton.click()

The x-challenge and x-signature cookies set by grok.com are Cloudflare challenge cookies, NOT valid API authentication tokens. When captured as "SSO tokens", they will fail with "Incorrect API key provided" when used with api.x.ai/v1.

Valid tokens are obtained via:

  1. OAuth device code flow (via gw46.py gateway or grok login --device-auth)
  2. Direct OAuth PKCE flow (via gw46.py /oauth/login endpoint)
  3. The auth.json file at ~/.grok/auth.json (written by grok login --oauth or grok login --device-auth)

Ready-Made Gateway: gw46.py

Location: C:\Users\User\Documents\grok46gw/gw46.py

Features:

  • OpenAI-compatible API (/v1/chat/completions, /v1/responses)
  • Multi-model support: grok-4.6, grok-4.5, grok-4.3, grok-build-0.1
  • OAuth auto-registration with PKCE flow (/oauth/login)
  • Device code flow (/oauth/device, /oauth/device/poll)
  • SQLite account database (grok46_accounts.db)
  • API key pool with round-robin rotation
  • Token refresh support

Usage:

cd ~/Documents/grok46gw
python gw46.py  # starts on 127.0.0.1:20146

Getting tokens via device code flow:

GET http://127.0.0.1:20146/oauth/device  → returns user_code + verification_uri
User opens verification_uri, signs in, enters user_code, authorizes
GET http://127.0.0.1:20146/oauth/device/poll  → returns token

DuckMail: Primary Temp Email Provider (2026-08-13)

DuckMail (api.duckmail.sbs) is the preferred temporary email provider. It is a mail.tm-compatible API that works without any bearer token and has no practical rate limits (19 domains, rotates automatically).

Why DuckMail Over mail.tm

Feature DuckMail mail.tm
Bearer token required No No
Rate limit None observed 429 after 3-4/min
Available domains 19 (growing) ~5
API compatibility mail.tm-compatible Native
Observed success rate ~95% ~30% under load

Switching from mail.tm to DuckMail

Change the API base URL in email_service.py:

MAILTM_BASE = "https://api.duckmail.sbs"  # was "https://api.mail.tm"

All mail.tm-compatible code works unchanged.

Available Domains (2026-08-13)

duckmail.sbs, niceground.shop, stoneground.shop, lakeground.shop, canvaspace.shop, vercelspace.shop, seedancespace.shop, happyhorsespace.shop, bananaspace.shop, sunstarmoon.shop, moonstarsun.shop, sunmoonlight.shop, makesomestone.shop, mikesomelike.shop, somestoneair.shop, hubaiclass.org, markaihub.shop, markstonehub.org, glasswhitehub.com

PRIMARY Working Method: curl_cffi + gRPC-web (GrokRegister)

Location: C:\Users\User\tmp\grok_register\grok-register\grok.py

This is the only consistently working approach as of 2026-08-13. Uses curl_cffi (TLS fingerprint emulation) and direct gRPC-web API calls — no browser needed.

Flow

  1. Initialize: Fetch sign-up page, extract action_id from JS chunks, site_key and state_tree from HTML
  2. Create email: DuckMail API → fresh disposable email
  3. Send OTP: gRPC-web call to auth_mgmt.AuthManagement/CreateEmailValidationCode
  4. Wait for OTP: Poll DuckMail inbox for verification code
  5. Solve Turnstile: 2captcha (TurnstileTaskProxyless)
  6. Submit registration: POST /sign-up with next-action header, OTP, Turnstile token, account details
  7. Extract SSO: Parse response for set-cookie?q= URL, follow it, capture sso cookie
  8. Save: Write SSO token to keys/grok.txt and account to keys/accounts.txt

Key Code

# gRPC-web message encoding
def encode_grpc_message(field_id, string_value):
    key = (field_id << 3) | 2
    value_bytes = string_value.encode('utf-8')
    length = len(value_bytes)
    payload = struct.pack('B', key) + struct.pack('B', length) + value_bytes
    return b'\x00' + struct.pack('>I', len(payload)) + payload

# Send OTP via gRPC-web
session.post(f"{site_url}/auth_mgmt.AuthManagement/CreateEmailValidationCode",
    data=encode_grpc_message(1, email),
    headers={"content-type": "application/grpc-web+proto", "x-grpc-web": "1",
             "x-user-agent": "connect-es/2.1.1"})

# Submit registration with Next.js server action
headers = {
    "next-action": action_id,  # from JS chunks
    "next-router-state-tree": state_tree,  # from HTML
    "accept": "text/x-component",
}
payload = [{
    "emailValidationCode": otp_code,
    "createUserAndSessionRequest": {
        "email": email, "givenName": "Test", "familyName": "User",
        "clearTextPassword": password, "tosAcceptedVersion": "$undefined"
    },
    "turnstileToken": token, "promptOnDuplicateEmail": True
}]
session.post(f"{site_url}/sign-up", json=payload, headers=headers)

Usage

cd /c/Users/User/tmp/grok_register/grok-register
export TWOCAPTCHA_API_KEY="[REDACTED-KEY]"
python3 grok.py --threads 8 --count 100

Performance

  • ~2.6 seconds per account with 8 threads
  • ~95% success rate (DuckMail, no rate limit)
  • No browser needed — headless, curl_cffi for TLS fingerprinting

Files

  • grok.py — Main script (thread pool, action ID, registration flow)
  • email_service.py — mail.tm/DuckMail API client
  • YesCaptcha_service.py — 2captcha Turnstile solver
  • keys/grok.txt — SSO tokens (one per line)
  • keys/accounts.txt — Account details (email:password:sso)

SSO Token → OAuth Token Conversion (Device Auth Flow)

SSO cookies from GrokRegister are NOT valid API keys for api.x.ai/v1. They return "Incorrect API key provided". To get OAuth tokens that work with the API gateway, use the device auth flow with DrissionPage to auto-authorize each SSO session.

CRITICAL: Accounts Have No API Credits

Even after successful SSO → OAuth conversion, the accounts have no API credits. The x.ai API returns 402 personal-team-blocked:spending-limit — accounts need a SuperGrok subscription or API credits. The OAuth tokens are valid (scope includes api:access) but the upstream rejects all requests. The gw46 gateway will show credentials: N in health but every API call fails with 402.

Workarounds being investigated:

  • Check if new accounts get free trial credits after email verification
  • Use Grok website API (grok.com/rest/) with SSO cookies instead of api.x.ai
  • Use a different provider entirely

Automated SSO → OAuth Conversion (Working Method)

Script: sso2oauth.py in the GrokRegister directory.

Prerequisites:

  • DrissionPage (installed globally, import with python -s to avoid Hermes venv path issues)
  • httpx, sqlite3 (stdlib)
  • Chrome installed at C:\Program Files\Google\Chrome\Application\chrome.exe
  • gw46 gateway DB at ~/Documents/grok46gw/grok46_accounts.db

Flow:

  1. Read SSO tokens from keys/accounts.txt (format: email:password:sso)
  2. Start OAuth device code flow: POST https://auth.x.ai/oauth2/device/code
  3. Launch DrissionPage with SSO cookie injected into accounts.x.ai domain
  4. Navigate to verification_uri_complete (includes user_code in URL)
  5. Click "Продолжить" (Continue) to submit the code
  6. Click "Authorize" / "Разрешить" to grant device authorization
  7. Poll for OAuth token: POST https://auth.x.ai/oauth2/token with grant_type=device_code
  8. Store token in gw46 SQLite DB via INSERT INTO accounts

Usage:

cd ~/tmp/grok_register/grok-register
python -s sso2oauth.py --concurrent 1 --count 10
python -s sso2oauth.py --start 10 --count 50

Parameters:

  • --count N: number of accounts to process (0 = all)
  • --start N: start index
  • --concurrent N: concurrency (DrissionPage crashes with >1, use always 1)

DrissionPage Concurrency Limitation (CRITICAL): DrissionPage 4.1.0 raises PageDisconnectedError (与页面的连接已断开) when multiple ChromiumPage instances are created in the same process — even with asyncio.Semaphore. The background event handler thread crashes. Always use --concurrent 1 (sequential processing). For large batches, split into chunks and restart the Python process between chunks to clear DrissionPage's internal state (~10-15 accounts per process before memory leaks cause crashes).

Performance:

  • ~10-15 seconds per account (sequential)
  • ~74 accounts processed in ~12 minutes

gw46 Gateway KeyPool Refresh

After adding tokens to the SQLite DB externally (via sso2oauth.py), the gw46 gateway's in-memory KeyPool is NOT automatically refreshed. The gateway only reads the DB during startup (lifespan event) and when /oauth/callback or /accounts/api-key endpoints are called.

To refresh after external DB writes:

  1. Kill the gateway: taskkill /F /PID <PID>
  2. Restart: cd ~/Documents/grok46gw && python gw46.py
  3. Verify: curl http://127.0.0.1:20146/health — credentials count should match DB total

gw46 Gateway Integration (Manual)

  1. Start gw46: python Documents/grok46gw/gw46.py (port 20146)
  2. Get device code: GET /oauth/device
  3. Auth in browser with SSO cookie → authorize
  4. Poll for token: GET /oauth/device/poll
  5. Token stored in gw46 SQLite, used for API proxying

Working Approach (v13 — Deprecated)

The custom Playwright scripts (v13, v16, v20) are deprecated in favor of the ready-made solutions above. They are kept for reference but the DrissionPage-based approach + gw46.py gateway is more reliable.

C:\Users\User\Desktop\авторег проект\grok_autoreg_v13.py

v11 is NOT usable — the file at _SCRIPTS/grok_autoreg_v11.py has a syntax error (broken indentation at line 80-81, for part in msg.walk(): is not indented after if msg.is_multipart():). Do NOT reference v11 as a working alternative unless the file has been repaired.

Which to use: Always use v13. v11 exists at _SCRIPTS/ but is non-functional.

Key insight: Signup happens INSIDE the device-auth OAuth flow, NOT before it.

Flow

  1. Start grok login --device-auth → get device URL
  2. Open device URL in browser → click Continue → redirected to sign-in
  3. Click "Sign up" (NOT "Login") on the sign-in page
  4. Click "Sign up with email" → fill email → submit
  5. Solve Turnstile (2Captcha) on sign-up page
  6. Get OTP from IMAP (t-online.de) → enter code via type() (not fill())
  7. On verification page: solve Turnstile again → click submit
  8. On profile form: fill name + surname + password via fill() + dispatch input event → click "Завершить регистрацию"
  9. CRITICAL: Navigate BACK to the device auth URL → click Continue → click Authorize/Allow
  10. Token appears in ~/.grok/auth.json → add to token_pool.json

Device Auth Flow Is NOT Automatic

After signup completes, the browser is NOT automatically redirected to the auth callback. You MUST:

  1. Navigate back to the device auth URL
  2. Click "Continue" (user is now logged in, so it shows the authorization page)
  3. Click "Authorize" or "Allow"
  4. ONLY THEN does the device auth CLI receive the callback and write the token

Without step 9, the account is created but the token is NEVER saved — the device auth CLI times out waiting for a callback that never arrives.

Dependencies

  • patchright (NOT playwright): pip install patchright
  • requests: pip install requests (used by 2Captcha solver)
  • 2Captcha key: [REDACTED-KEY] (the bd9c67... key is DEAD)
  • IMAP: t-online.de via secureimap.t-online.de:993
  • Browser: Uses launch_persistent_context with channel="chrome" and user_data_dir=r"C:\Users\User\Desktop\browser_profile_grok"
  • Emails file: C:\Users\User\Downloads\Telegram Desktop\working_mails.txt (format: email:password)

Usage

cd "C:\Users\User\Desktop\авторег проект"
PYTHONPATH="" .venv/Scripts/python -u "C:/Users/User/projects/_uncategorized_projects/_SCRIPTS/grok_autoreg_v11.py" 100

Argument = number of accounts to register.

CRITICAL PITFALL: Do Not Fix What Is Not Broken

When Vlad says the software "worked before" and it is failing now:

  1. DO NOT modify the script — search the ENTIRE PC for working versions first
  2. Use search_files with *grok*autoreg* across C:\Users\User
  3. The Desktop\авторег проект\grok_autoreg.py is NOT the working version — it is a different (broken) approach
  4. Multiple versions exist: _SCRIPTS/grok_autoreg_v4.py through v11.py

Environment Issues

PYTHONPATH Pollution

The global PYTHONPATH points to hermes-agent-0.18.2-latest\\venv which has broken permissions. Always prefix with PYTHONPATH="" when running from a local venv.

Python -s Flag for DrissionPage

The Hermes venv (hermes-agent-0.18.2-latest/venv/) has broken file permissions on Playwright packages. When running DrissionPage from the global Python, use python -s to skip user site-packages — this avoids the permission error on playwright/__init__.py. Without -s, DrissionPage imports fail with PermissionError: [Errno 13] because Python scans the Hermes venv first.

# Correct way to run DrissionPage scripts globally
python -s sso2oauth.py --count 10

Venv Setup

cd "C:\Users\User\Desktop\авторег проект"
python -m venv .venv
PYTHONPATH="" .venv/Scripts/pip install patchright

Token Pool

  • Location: ~/.grok/token_pool.json
  • Format: {"tokens": [{"email": ..., "access_token": ..., "refresh_token": ..., "expires_at": ...}]}
  • Tokens expire after ~6 hours, auto-refresh via TokenPool.get_valid()

Fixes Applied to v11 (2026-08-13)

IMAP: UNSEEN Filter + Socket Timeout

The original mail.search(None, "ALL") hangs on large mailboxes (5000+ emails). Fixed:

  1. Use mail.search(None, '(UNSEEN FROM "x.ai")') with fallback to mail.search(None, "UNSEEN") — searches only new emails, not entire mailbox
  2. Add mail = imaplib.IMAP4_SSL(IMAP_HOST, IMAP_PORT, timeout=30) and mail.socket().settimeout(30) to prevent hanging on slow connections
  3. Wrap each search in a try/except to catch socket timeouts

Code Entry: type() Instead of fill()

code_input.fill(vcode) does not trigger form validation events. Fixed to use code_input.type(code_clean, delay=80) with dash removed (vcode.replace("-", "")).

button:has-text('Подтвердить') matches the OneTrust cookie consent button onetrust-close-btn-handler. Fixed by checking class attribute for "onetrust" and skipping those buttons.

JS querySelector with :has-text() Is Invalid

document.querySelector('button:has-text("...")') throws SyntaxError because :has-text() is a Playwright pseudo-selector, NOT a valid CSS selector. Use only page.locator("button:has-text('...')") in Playwright context. For JS fallback, use loop with textContent.includes():

Missing "Завершить регистрацию" Button

The profile completion form uses "Завершить регистрацию" (Complete registration), not "Sign up" or "Далее". Added to the button text list in Step 11.

Profile Form: fill() + dispatchEvent('input') for React

The profile form (name, surname, password) uses React controlled inputs. Using Object.getOwnPropertyDescriptor(...).set bypasses React's change detection — the form sees empty values and refuses to submit. Fix:

  1. Use locator.fill() for all three fields
  2. After each fill(), dispatch an input event via page.evaluate("document.querySelector('input[...]')?.dispatchEvent(new Event('input', {bubbles: true}))")
  3. Then click the submit button via Playwright locator (NOT JS querySelector with :has-text() — that's a Playwright pseudo-selector, not valid CSS)
  4. Use Playwright locator: page.locator("button:has-text('Завершить регистрацию')").first

Turnstile on Verification Page

The verification code page also has a Turnstile captcha. Added detection and solving in Step 10 (before clicking submit).

Rate-Limiting Avoidance

x.ai throttles after 1-2 repeated attempts on the same email. The script skips rate-limited emails automatically. Do NOT re-run the same email repeatedly — move to a fresh one.

Other Versions (for reference)

  • v4–v10: Various iterations in _SCRIPTS/
  • grok_cdp_autoreg.py: CDP-based approach (may work differently)
  • _PROJECTS/grok_autoreg.py: Another project variant
  • Desktop\авторег проект\grok_autoreg.py: The BROKEN version (signup-then-auth, does not work)

v16: OAuth-After-Signup + Persistent Context (2026-08-13)

v16 is the current working approach. Key improvements over v11-v15:

Persistent Context with Temp User Data Dir

  • Uses launch_persistent_context(user_data_dir=temp_dir, channel="chrome") — NOT launch()
  • Temp directory per registration (no session leakage across accounts)
  • --disable-blink-features=AutomationControlled is REQUIRED for Turnstile to work
  • Without channel="chrome": form submission consistently fails (GET params instead of POST redirect)
  • With channel="chrome": form submission works ~50% of the time (Turnstile-dependent)

Form Submission Pattern (v16 Working)

The profile page form submission is flaky. The pattern that works:

  1. Solve Turnstile on profile page (sitekey 0x4AAAAAAAhr9JGVDZbrZOo0)
  2. Inject token via querySelectorAll('input[name="cf-turnstile-response"]') + string interpolation
  3. Click "Завершить регистрацию" button via Playwright locator
  4. Wait 3s, then force form.submit() via JS on the form containing password input
  5. Wait 5s for redirect
  6. If still on sign-up (GET params in URL), the account may still have been created — proceed to OAuth

OAuth Timing Fix

CRITICAL: grok login --oauth times out after ~2 minutes. Signup takes 3-5 minutes (IMAP + Turnstile).

  • BEFORE v16: OAuth was started before signup → CLI times out → callback received but no token saved
  • v16 FIX: Device auth for signup, OAuth started AFTER signup completes → CLI is fresh, no timeout

Flow (v16)

  1. Clear auth.json (backup to .bak, restore if empty)
  2. grok login --device-auth → get device URL
  3. Browser: device URL → Continue → Sign up → Sign up with email
  4. Fill email → submit → IMAP code → enter code
  5. Turnstile on code page (often unsolvable, page advances anyway)
  6. Profile form: fill name/surname/password → Turnstile on profile → solve
  7. Click "Завершить регистрацию" → force form.submit()
  8. If redirected to consent page: click "Authorize" → device auth CLI gets token
  9. If device auth fails: grok login --oauth (fresh) → navigate to OAuth URL → consent page → Authorize
  10. Extract token from auth.json (newest entry, sorted by key)

Success Rate & Token Validation

  • Form submission redirects to consent page ~50% of runs
  • When it does: token is valid for the NEW account
  • When it doesn't: OAuth fallback, but account may not have been created → no token
  • Always validate tokens: curl https://api.x.ai/v1/models -H "Authorization: Bearer TOKEN"
  • Pool tokens may show "valid" (based on expiry time) but fail API calls due to wrong account binding

Current Working Script

C:\Users\User\Desktop\авторег проект\grok_autoreg_v16.py

Commands: register, batch N, pool, proxy [port], health, test

Lock File & Stale Process Cleanup

Before running ANY grok login command, cleanup stale state:

import subprocess, os

# Kill stale grok processes
subprocess.run(["taskkill", "/f", "/im", "grok.exe"], capture_output=True, timeout=5)

# Remove lock files that block fresh auth
for f in [AUTH_JSON + ".lock", os.path.join(GROK_HOME, "leader.sock")]:
    if os.path.exists(f):
        os.remove(f)

Without this, grok logout and grok login --device-auth hang indefinitely with TimeoutError.

Turnstile Timeout Parameter

The solve_turnstile() function now supports a timeout parameter (seconds, default 30). The code-page Turnstile (sitekey 0x4AAAAAAADnQ4F4U8W2nQyH) is ALWAYS unsolvable via 2captcha — do not wait 5 minutes for it:

token = await solve_turnstile(sk, page.url, timeout=30)
if token:
    # inject
else:
    print("unsolvable/timeout — continuing anyway")

The profile-page Turnstile (sitekey 0x4AAAAAAAhr9JGVDZbrZOo0) IS solvable (~30s). Use the same timeout.

React SPA: No HTML Forms (v19-v20 Finding)

The x.ai signup page (/sign-up) is a React SPA that does NOT contain <form> elements. The signup is done through JavaScript API calls (likely Zitadel API). This means:

  • form.submit() from JS does NOTHING useful (navigates to GET params URL)
  • page.keyboard.press("Enter") also does NOTHING (no form to submit)
  • The button click triggers a React event handler that makes an API call
  • Even with valid Turnstile tokens injected into cf-turnstile-response hidden inputs, the React event handler may not check that input

As of v20, the form submission is the unsolved bottleneck. The Turnstile is solved, the token is injected, but the server rejects the submission ~90% of the time. Flow degrades to:

  1. Signup form stuck → account NOT created
  2. Device auth CLI waiting → no callback → timeout
  3. OAuth fallback → logs into old account → invalid token (403)

v20 discovery: cf_clearance cookie auto-solves on real Chrome (channel="chrome"). The cookie can be extracted and used for direct API calls. However, ALL x.ai API endpoints (/api/v2/authn/verification_code, /api/v2/users/human, etc.) return HTML (Next.js page) instead of JSON — the API is not directly accessible behind the Next.js frontend, even with a valid cf_clearance cookie.

Known Failure Mode: API Token Validation

Even when token_pool.json shows tokens as "valid" (based on expires_at), they may return 403 {"code":"unauthenticated:bad-credentials","error":"The OAuth2 access token could not be validated."}. This happens when the OAuth flow authorized the WRONG account (existing account instead of newly created one). Always validate with:

curl -s https://api.x.ai/v1/models -H "Authorization: Bearer TOKEN" | head -c 200

channel="chrome" Is Required

Without channel="chrome" in launch_persistent_context, the headless Chromium browser's Turnstile widget always shows a challenge (never auto-solves). With channel="chrome" (real Chrome), the widget auto-solves and sets cf_clearance cookie — no 2captcha needed for the WAF bypass. The cf_clearance cookie (cf_clearance = MeLLMwuSWSia66h6...) is set automatically after page load on real Chrome. However, the Turnstile widget on the profile form STILL needs manual solving (2captcha) because it's a separate challenge.

Always use:

browser = await pwr.chromium.launch_persistent_context(
    headless=False,
    channel="chrome",  # REQUIRED — Turnstile auto-solves WAF with real Chrome
    args=["--window-size=1200,900", "--disable-blink-features=AutomationControlled", "--no-sandbox"]
)

Reference Files

  • references/imap-pattern.md — IMAP verification code extraction with UNSEEN filter
  • references/react-form-filling.md — React controlled form filling with fill() + input event
  • references/device-auth-completion.md — Device auth flow completion after signup
  • references/oauth-fallback-token.md — OAuth fallback pattern for token retrieval
  • references/oauth-account-mismatch.md — OAuth authorizes wrong account (token bound to old account)
  • references/oauth-timing-account-binding.md — OAuth CLI timeout + account binding fix (v16)
  • references/turnstile-json-escape.md — Turnstile token JSON escaping
  • references/form-submission-pattern.md — Profile form submission pattern (v16 working)
  • references/profile-turnstile-timing.md — Profile Turnstile iframe detection timing fix
  • references/duckmail-api.md — DuckMail API reference (no auth, 19 domains, no rate limit)
  • references/curl-cffi-grpc-web.md — curl_cffi + gRPC-web registration approach (PRIMARY working method)
  • references/playwright-stealth-setup.md — Playwright stealth import pattern + Cloudflare bypass (2026-08-14)
  • references/bpproxy-pool.md — bpproxy residential proxy pool location + usage (2026-08-14)
  • references/tonline-email-pool.md — t-online.de email pool (17,893 accounts) + IMAP settings (2026-08-14)