Skip to main content
Peak — solve Cloudflare Turnstile & the 5s challenge in ~1s

turnstile-curl

turnstile-curl is a curl_cffi companion that solves Cloudflare Turnstile without a browser, so a curl_cffi request that hits a Turnstile wall comes back with a real token instead of a 403.

Why

curl_cffi forges a browser's TLS/JA3 handshake perfectly, which is exactly why people reach for it. But it has no JavaScript engine. Cloudflare Turnstile is a JS widget, so a managed or interactive challenge hands curl_cffi an interstitial HTML page or a 403, and there is nothing in-process that can run the challenge. This is the "curl_cffi cloudflare blocked" wall: the handshake is right, the request still fails.

turnstile-curl reads the Turnstile sitekey straight out of the returned markup, sends it to Peak, and gives you back the cf-turnstile-response token. curl_cffi still does the fetching, so you keep its speed and fingerprint. When your setup gets blocked, drop in a Peak API key and it just works.

Powered by Peak

This package uses Peak to solve Turnstile.

  • Solve Cloudflare Turnstile & the 5s challenge in about a second
  • Pay only for successful solves — from $1 / 1,000
  • 1,000 free solves to start, no card.

Get your free API key · Docs · Pricing

Install

pip install turnstile-curl curl_cffi

curl_cffi is the transport you fetch pages with. It is an optional dependency here so the library imports cleanly without it; install it to actually fetch.

Quickstart

import os
from turnstile_curl import solve

# Free key at https://peak.fo.?utm_source=github&utm_medium=readme&utm_campaign=packages&utm_content=turnstile-curl Reads PEAK_API_KEY by default.
os.environ.setdefault("PEAK_API_KEY", "pk_your_api_key")

# Fetch the protected page with curl_cffi, read the sitekey, solve via Peak.
token = solve("https://your-target.example/login")
print(token)  # -> "0.AgAAA..."  (the cf-turnstile-response value)

Send token as the cf-turnstile-response form field (or into the widget callback) on your next request.

Session: solve and resubmit in one shot

TurnstileSession wraps a curl_cffi session and keeps the same browser fingerprint through the whole flow.

from turnstile_curl import TurnstileSession

with TurnstileSession(api_key="pk_your_api_key", impersonate="chrome") as s:
    # Just the token:
    token = s.solve("https://your-target.example/login")

    # Or solve + resubmit the form with the token injected, and keep the
    # authenticated response and cookies on the session:
    resp = s.solve_and_submit(
        "https://your-target.example/login",
        submit_url="https://your-target.example/verify",
        data={"username": "demo", "password": "demo"},
    )
    print(resp.status_code)

Already have the sitekey

Skip the fetch and call Peak directly.

from turnstile_curl import PeakClient

peak = PeakClient(api_key="pk_your_api_key")
token = peak.solve_turnstile(
    sitekey="0x4AAAAAAADnPIDROrmt1Wwj",
    url="https://your-target.example/login",
    # proxy="http://user:pass@ip:port",  # optional
)

Proxies

Pass proxy="http://user:pass@ip:port" to TurnstileSession, solve(), or PeakClient.solve_turnstile(). The same proxy is used for the page fetch and forwarded to Peak so the token is minted from the IP you will use it on.

How it works

  1. curl_cffi fetches the page with a forged browser TLS/JA3 fingerprint.
  2. turnstile-curl parses the sitekey (and cData / action / pagedata when present) from the data-sitekey container or a turnstile.render(...) call.
  3. It calls POST https://api.peak.fo/solve with task_type: "turnstiletask", the sitekey, and the URL.
  4. Peak returns the token; you resubmit the form with it as cf-turnstile-response.

Peak also solves the Cloudflare 5s challenge (task_type: "cloudflare5stask"); this package focuses on Turnstile.

API

  • solve(url, *, api_key=None, impersonate="chrome", proxy=None) -> str — one-shot fetch + solve, returns the token.
  • TurnstileSession(api_key=None, *, impersonate="chrome", proxy=None).get(), .solve(url), .detect_challenge(url), .solve_and_submit(url, ...).
  • PeakClient(api_key=None).solve(challenge), .solve_turnstile(sitekey, url, ...).
  • parse_challenge(html, url) / find_sitekey(html) — the extractor, if you fetch pages yourself.

The API key is read from PEAK_API_KEY unless you pass api_key=.

Legitimate use

For automation, QA, and scraping public data you are allowed to access. Respect each target's Terms of Service and robots.txt, and rate-limit yourself. Do not use this for credential stuffing or to access data you have no right to.

License

MIT — see LICENSE.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

turnstile_curl-0.1.0.tar.gz (11.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

turnstile_curl-0.1.0-py3-none-any.whl (11.4 kB view details)

Uploaded Python 3

File details

Details for the file turnstile_curl-0.1.0.tar.gz.

File metadata

  • Download URL: turnstile_curl-0.1.0.tar.gz
  • Upload date:
  • Size: 11.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.12.0

File hashes

Hashes for turnstile_curl-0.1.0.tar.gz
Algorithm Hash digest
SHA256 e612ad519de48fd9f7bd6a62f2662319e4bd94fc6cbcc8af54c9b3dd0d821712
MD5 e5cb417b5aaac30bbfd51a7fda640253
BLAKE2b-256 b006bc954e5d181e85dad1b5c2abd6c158490775e051807897ac37a9fc2defca

See more details on using hashes here.

File details

Details for the file turnstile_curl-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: turnstile_curl-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 11.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.12.0

File hashes

Hashes for turnstile_curl-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 4e48f85c65f10cada13e907fa60340692c86aec16dd751d0c060e021080a8acb
MD5 4a8c94f36e5738e7364e267e67f4d5c5
BLAKE2b-256 21025a156f21497e67418933dc57e935538e977ef907b12dbc28271cd1881224

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page