Production-oriented Cloudflare Turnstile solver API built with Quart, Patchright, and Camoufox.
This repository is a cleaned, public-safe showcase of a real deployment. It preserves the core implementation and practical improvements while excluding runtime state, private infrastructure details, and local machine-specific configuration.
- Async HTTP API powered by Quart
- Concurrent browser worker pool
- Support for
chromium,chrome,msedge, andcamoufox - Optional browser fingerprint rotation from a curated config pool
- Optional proxy support via a local
proxies.txt - SQLite result storage with WAL mode enabled
- Automatic cleanup for older task results
- Optional helper flow for pages that gate Turnstile behind an address/email step
- Optional helper flow for pages that require clicking a verification trigger before the widget appears
This showcase intentionally excludes:
- live VPS deployment details
- tunnel or reverse-proxy configuration
- runtime databases and logs
- local secrets, private addresses, and machine-specific state
api_solver.py- main API server and solving workflowbrowser_configs.py- browser fingerprint configuration pooldb_results.py- SQLite persistence helpersrequirements.txt- Python dependenciesproxies.example.txt- example proxy list format.env.example- optional environment configuration example
- Python 3.10+
- Linux, macOS, or Windows
- One supported browser backend:
- Patchright Chromium
- Google Chrome
- Microsoft Edge
- Camoufox
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txtInstall the browser runtime for the backend you plan to use.
python -m patchright install chromiumInstall Chrome on your system, then run the API with --browser_type chrome.
python -m patchright install msedgepython -m camoufox fetchIf you need the optional address or email pre-submit helper flow:
cp .env.example .envEnvironment variables:
TURNSTILE_LOGIN_ADDRESS- optional value submitted to pages that gate verification behind an input namedaddress
If you want proxy support, create a local proxies.txt file using one entry per line.
Supported formats:
ip:port
ip:port:username:password
scheme://ip:port
scheme://username:password@ip:port
A sample format file is included as proxies.example.txt.
Basic local run:
python api_solver.py --browser_type chromium --host 127.0.0.1 --port 5000Example with Chrome and debug logging:
python api_solver.py --browser_type chrome --host 127.0.0.1 --port 5000 --debug| Argument | Description |
|---|---|
--no-headless |
Run the browser with a visible UI |
--useragent |
Provide a custom user-agent string |
--debug |
Enable verbose logging |
--browser_type |
Choose chromium, chrome, msedge, or camoufox |
--thread |
Number of browser workers |
--host |
Bind address |
--port |
Listening port |
--proxy |
Enable proxy usage from proxies.txt |
--random |
Randomize browser config from the bundled pool |
--browser |
Select an explicit browser name from the config pool |
--version |
Select an explicit browser version from the config pool |
GET /turnstile?url=https://example.com&sitekey=0x4AAAAAAAOptional query parameters:
actioncdata
Example:
curl "http://127.0.0.1:5000/turnstile?url=https://example.com&sitekey=0x4AAAAAAA"Example response:
{
"errorId": 0,
"taskId": "d2cbb257-9c37-4f9c-9bc7-1eaee72d96a8"
}GET /result?id=d2cbb257-9c37-4f9c-9bc7-1eaee72d96a8Processing response:
{
"status": "processing"
}Ready response:
{
"errorId": 0,
"status": "ready",
"solution": {
"token": "0.xxxxx"
}
}Failure response:
{
"errorId": 1,
"errorCode": "ERROR_CAPTCHA_UNSOLVABLE",
"errorDescription": "Workers could not solve the Captcha"
}- The root route (
/) serves a simple built-in usage page. - SQLite results are stored locally and are intentionally excluded from version control.
- This repository is meant to present the source cleanly, not to mirror live runtime state.
Use this project only where you are authorized to automate, test, or evaluate the target flow.