peakfo is the official Python client for Peak, an API that solves Cloudflare Turnstile and the Cloudflare 5-second challenge. It wraps the POST /solve endpoint, so a solve is one method call.
Peak bills only for solves that succeed. New accounts get 1,000 free solves, no card.
pip install peakfosolve_turnstile returns a token. Submit it as the cf-turnstile-response field of the form you are posting.
from peakfo import PeakClient
client = PeakClient("pk_your_api_key")
result = client.solve_turnstile(
sitekey="0x4AAAAAAAxxxxxxxx",
url="https://example.com/",
proxy="http://user:pass@ip:port",
)
print(result["token"])Leave proxy out and the solve runs through Peak's own pool instead (the TurnstileTaskProxyLess task). That works for sites that accept the token from any IP. If a site ties the token to the IP that solved it, pass your own proxy.
The sitekey is scoped to the target domain, and the API expects the URL to end with a trailing slash. If the widget sets an action or cdata value, pass the same values:
client.solve_turnstile(sitekey, url, proxy=proxy, action="login", cdata="session-42")Not sure where the sitekey lives? See How to find a Cloudflare Turnstile sitekey.
result = client.solve_cloudflare_waf(
url="https://example.com/",
proxy="http://user:pass@ip:port", # sticky session proxy
)
cookies = result["cookies"] # includes cf_clearance
user_agent = result["headers"]["user-agent"] # use this exact string from now onCloudflare checks that one IP carries the whole session, so use a sticky proxy and keep it for every request that uses the clearance. Only Windows Chrome user agents are supported. To finish the challenge, apply the cookies, POST result["attributes"] form-encoded to the target URL with the Referer set to {url}?__cf_chl_tk={result["cf_rt"]}, then reuse the session. The API docs walk through the four steps, and the cf_clearance explainer covers reusing the cookie.
print(client.get_balance()) # {'type': 'pay_per_solve', 'balance': ...}Every failure raises a subclass of PeakError.
from peakfo import (
PeakClient, PeakError, AuthenticationError,
InsufficientBalanceError, SolveError, TaskDisabledError,
)
try:
result = client.solve_turnstile(sitekey, url, proxy=proxy)
except AuthenticationError:
... # missing or invalid API key
except InsufficientBalanceError:
... # top up, or the package is used up
except TaskDisabledError:
... # that task type is switched off right now
except SolveError as e:
... # the solve failed; it was not billed, so retrying is free
except PeakError as e:
... # network error or a non-JSON replyPeakClient(api_key, timeout=120) sets the request timeout in seconds.
If you build a tool on top of Peak, create an app ID under Dashboard, Developer, and pass it as app_id to any solve method. Peak credits you 5% of the cost of every solve that carries it. The field is optional and has no effect on the solve.
client.solve_turnstile(sitekey, url, app_id="app_your_app_id")Turnstile is $0.90 per 1,000 successful solves, dropping to $0.35 per 1,000 on the largest package. The 5-second challenge is $1.00 per 1,000. Current numbers are on peak.fo.
solve_aws_waf is still in the client, but the task is switched off on Peak's side, so calling it raises TaskDisabledError.
Peak also publishes drop-in wrappers for Playwright, Puppeteer, Selenium, Scrapy, curl_cffi and cloudscraper.
1.1.0
solve_turnstileaccepts no proxy and switches to the proxyless task.- New optional arguments:
app_id, anduser_agentandhtmlon the 5-second challenge. - Non-JSON replies and network errors raise
PeakErrorinstead of a raw exception. timeoutis now a constructor argument.- Fixed the README: the free trial is 1,000 solves, and the old price table is gone.
1.0.0 first release.
Meant for QA, public-data collection and automation you are allowed to run. Follow each target's terms and robots rules.
MIT licensed. Support: support@peak.fo.