Cloudflare Turnstile
A Cloudflare Turnstile task returns a token (token) that you submit to the target site to pass the check. TurnstileTaskProxyless costs 25 points (¥0.025) per task and is asynchronous: createTask, then getTaskResult every 5 seconds. Failed and timed-out tasks are refunded automatically.
https://api.yescaptcha.com/createTaskGlobal endpointhttps://cn.yescaptcha.com/createTaskChina endpointThe request body is JSON authenticated with your clientKey. Query results on the same endpoint you created the task on.
When to use
Section titled “When to use”A Cloudflare verification widget (“Verify you are human”) is embedded in a form on the page, and the page loads a script from challenges.cloudflare.com/turnstile.
If the whole page is replaced by Cloudflare’s “Just a moment…” / “Checking your browser” screen, that is the challenge page, not Turnstile; use Cloudflare challenge page. See Identify the captcha type.
Task types and pricing
Section titled “Task types and pricing”| Task type | Price | Mode | Notes |
|---|---|---|---|
TurnstileTaskProxyless | 25 points (¥0.025) | Asynchronous | |
TurnstileTaskProxylessM1 | 30 points (¥0.03) | Asynchronous | |
TurnstileTask | 25 points (¥0.025) | Asynchronous | Own proxy |
TurnstileTaskProxylessandTurnstileTaskProxylessM1take the same parameters on different routes; use either as a fallback for the other.TurnstileTaskloads the captcha through your own proxy and needs the proxy fields.
Request parameters
Section titled “Request parameters”| Field | Type | Required | Description |
|---|---|---|---|
type | string | Yes | Task type; see "Task types and pricing" on this page |
websiteURL | string | Yes | Full URL of the page that shows the captcha. Use the site you see the captcha on, not the captcha vendor's domain |
websiteKey | string | Yes | The Turnstile site key (sitekey), usually starting with 0x |
proxyType | string | Required for TurnstileTask | Proxy protocol: http, https, socks4 or socks5 |
proxyAddress | string | Required for TurnstileTask | Proxy IP address or hostname. Local or private addresses such as 127.0.0.1 or 192.168.x.x will not work because our servers cannot reach them |
proxyPort | integer | Required for TurnstileTask | Proxy port |
proxyLogin | string | No | Proxy username, if the proxy requires authentication (TurnstileTask only) |
proxyPassword | string | No | Proxy password, if the proxy requires authentication (TurnstileTask only) |
userAgent | string | No | Browser User-Agent. If the result contains a userAgent, use that value when you submit the token (TurnstileTask only) |
websiteKey usually starts with 0x. How to find it: Find Turnstile parameters.
Request example
Section titled “Request example”{ "clientKey": "YOUR_CLIENT_KEY", "task": { "type": "TurnstileTaskProxyless", "websiteURL": "https://example.com/login", "websiteKey": "0x4AAAAAAA_SITE_KEY" }}curl -s https://api.yescaptcha.com/createTask \ -H 'Content-Type: application/json' \ -d '{ "clientKey": "YOUR_CLIENT_KEY", "task": { "type": "TurnstileTaskProxyless", "websiteURL": "https://example.com/login", "websiteKey": "0x4AAAAAAA_SITE_KEY" }}'
# Returns {"errorId":0,"taskId":"..."}; then poll every 5 seconds:curl -s https://api.yescaptcha.com/getTaskResult \ -H 'Content-Type: application/json' \ -d '{"clientKey": "YOUR_CLIENT_KEY", "taskId": "TASK_ID"}'import osimport time
import requests
API = "https://api.yescaptcha.com"CLIENT_KEY = os.environ["YESCAPTCHA_CLIENT_KEY"] # Read the clientKey from an environment variable
def call(method, payload): r = requests.post(f"{API}/{method}", json={"clientKey": CLIENT_KEY, **payload}, timeout=30) data = r.json() if data.get("errorId"): raise RuntimeError(f"{data.get('errorCode')}: {data.get('errorDescription')}") return data
def solve(task): task_id = call("createTask", {"task": task})["taskId"] for _ in range(36): # Poll every 5 seconds, for up to about 3 minutes time.sleep(5) result = call("getTaskResult", {"taskId": task_id}) if result.get("status") == "ready": return result["solution"] raise TimeoutError(task_id)
solution = solve({ "type": "TurnstileTaskProxyless", "websiteURL": "https://example.com/login", "websiteKey": "0x4AAAAAAA_SITE_KEY",})print(solution["token"])const API = 'https://api.yescaptcha.com';const CLIENT_KEY = process.env.YESCAPTCHA_CLIENT_KEY; // Read the clientKey from an environment variable
async function call(method, payload) { const res = await fetch(`${API}/${method}`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ clientKey: CLIENT_KEY, ...payload }), }); const data = await res.json(); if (data.errorId) throw new Error(`${data.errorCode}: ${data.errorDescription}`); return data;}
async function solve(task) { const { taskId } = await call('createTask', { task }); for (let i = 0; i < 36; i++) { // Poll every 5 seconds, for up to about 3 minutes await new Promise((r) => setTimeout(r, 5000)); const result = await call('getTaskResult', { taskId }); if (result.status === 'ready') return result.solution; } throw new Error(`timeout: ${taskId}`);}
const solution = await solve({ type: "TurnstileTaskProxyless", websiteURL: "https://example.com/login", websiteKey: "0x4AAAAAAA_SITE_KEY",});console.log(solution.token);Replace websiteURL and websiteKey with the target site’s values.
Result
Section titled “Result”{ "errorId": 0, "status": "ready", "solution": { "token": "0.ufq5RgSVZd11DPSX1brdrxnEs28KcVlKj2ORchqxSy2q9yAW6ciq3hriXDF4x...", "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/155.0.0.0 Safari/537.36" }}| Field | Type | Description |
|---|---|---|
token | string | The token to submit to the target site. Single use; submit it as soon as possible |
userAgent | string | The User-Agent used to obtain the token. Use this value when you submit the token, even if it differs from the one you sent |
Put the token in the page’s cf-turnstile-response field (or the field the site’s API expects) and submit, using the returned userAgent as the User-Agent.
While in progress you get {"errorId": 0, "status": "processing"}; check again 5 seconds later. Handle errors by errorCode as described in Error codes.
How long is a token valid?
Section titled “How long is a token valid?”Single use. Submit it as soon as possible; Turnstile tokens usually expire within a few minutes (Cloudflare decides).
The site still rejects the submission
Section titled “The site still rejects the submission”Check that websiteURL is the page with the widget and websiteKey is correct, and submit with the returned userAgent. If the site also checks the IP, use TurnstileTask and submit through the same proxy.