Cloudflare Turnstile Solver: API Guide A Cloudflare Turnstile solver returns a valid turnstile token that your automation can drop into the cf-turnstile-response field so a legitimate form submission passes verification. This guide explains what Turnstile actually is, how it differs from Cloudflare's full-page challenge, and how to solve it programmatically with the OMOCaptcha API using complete, copy-pasteable Python examples. What is Cloudflare Turnstile? Cloudflare Turnstile is Cloudflare's privacy-first CAPTCHA alternative. Instead of forcing users to click grids of traffic lights, it runs a set of lightweight, often invisible browser checks and issues a short-lived token when it is satisfied the visitor is human. It is a drop-in replacement for reCAPTCHA and hCaptcha, and site owners embed it as a widget on login, signup, and contact forms. Turnstile is identified by a sitekey that starts with 0x... (for example 0x4AAAAAAA...). On success the widget writes its token into a hidden input named cf-turnstile-response. Your job as an automation engineer is to reproduce that token for the correct page. A captcha solver automates that reproduction step, so you do not have to reverse-engineer Turnstile's browser checks by hand. Turnstile vs. the Cloudflare interstitial challenge This is the single most common point of confusion, so it is worth stating plainly: Cloudflare Turnstile: - What it is: a widget you embed on a form - Output: a turnstile token in cf-turnstile-response - Where it lives: inside your HTML
- How you solve it: fetch a token, submit it with the form Cloudflare "Checking your browser" challenge: - What it is: a full-page interstitial protecting a whole site - Output: a clearance cookie (cf_clearance) - Where it lives: at the edge, before the page loads - How you solve it: solve the challenge in a real browser session A Turnstile solver produces a token, not challenge cookies. If you are stuck behind the interstitial "Just a moment..." page, that is the Cloudflare challenge, and it is handled differently (usually with a full browser session that keeps the cf_clearance cookie). Do not confuse the two. For the official widget reference, see the Cloudflare Turnstile docs (https://developers.cloudflare.com/turnstile/). How to solve Cloudflare Turnstile via API To solve Cloudflare Turnstile with an API, the flow is a simple token task: 1. Read the sitekey from the page: inspect the
element or the widget's render call, and note the full page URL. 2. createTask: send the sitekey and page URL to OMOCaptcha and receive a taskId. 3. getTaskResult: poll every few seconds until status is ready (or fail), with polite backoff. 4. Read the token and inject it into the cf-turnstile-response field, then submit the form the same way a browser would. The OMOCaptcha API V2 base URL is https://api.omocaptcha.com/v2, and every response returns HTTP 200; success or failure is decided by errorId (0 means success), and a task is locked to the API key that created it. Step 1: createTask Send a POST to /createTask with your clientKey and a Turnstile task object. As Python, the request body looks like this: payload = dict( clientKey="YOUR_API_KEY", task=dict( type="TurnstileTokenTask", websiteURL="https://example.com/login", websiteKey="0x4AAAAAAAxxxxxxxxxxxx", ), ) Note: TurnstileTokenTask follows the same createTask/getTaskResult flow as the confirmed task types. Confirm the exact type string for Turnstile in the OMOCaptcha API docs (https://omocaptcha.com/en?utm_source=blog&utm_medium=organic) before shipping to production. A successful response looks like this: dict(errorId=0, errorCode="", errorDescription="", taskId="abc123...") Step 2: getTaskResult Poll /getTaskResult with the same clientKey and your taskId. While the task is being worked it returns status: "processing"; when done it returns status: "ready" and a solution object containing the token, shaped like this: dict(errorId=0, status="ready", solution=dict(token="0.abc...")) Place solution.token into the cf-turnstile-response input and submit your form. Complete Python example import requests import time API_KEY = "YOUR_API_KEY" BASE = "https://api.omocaptcha.com/v2" TIMEOUT = 30 def create_task(): payload = dict( clientKey=API_KEY, task=dict( type="TurnstileTokenTask", # confirm exact type in OMOCaptcha docs websiteURL="https://example.com/login", websiteKey="0x4AAAAAAAxxxxxxxxxxxx", ), ) r = requests.post(BASE + "/createTask", json=payload, timeout=TIMEOUT) data = r.json() if data<>errorId"] != 0: raise RuntimeError("createTask failed: " + str(data.get("errorDescription"))) return data<>taskId"] def get_result(task_id): payload = dict(clientKey=API_KEY, taskId=task_id) delay = 3 for _ in range(20): # up to about a minute with backoff r = requests.post(BASE + "/getTaskResult", json=payload, timeout=TIMEOUT) data = r.json() if data<>errorId"] != 0: raise RuntimeError("getTaskResult error: " + str(data.get("errorDescription"))) status = data<>status"] if status == "ready": return data<>solution"]<>token"] if status == "fail": raise RuntimeError("Task failed to solve") time.sleep(delay) delay = min(delay + 2, 10) # polite backoff, cap at 10s raise TimeoutError("Turnstile task did not complete in time") if __name__ == "__main__": task_id = create_task() token = get_result(task_id) print("cf-turnstile-response =", token) Alternative Python example (standard library only, no external dependencies) import json import time import urllib.request API_KEY = "YOUR_API_KEY" BASE = "https://api.omocaptcha.com/v2" TIMEOUT = 30 def post_json(path, payload): body = json.dumps(payload).encode("utf-8") headers = dict(<>"Content-Type", "application/json")]) req = urllib.request.Request(BASE + path, data=body, headers=headers, method="POST") with urllib.request.urlopen(req, timeout=TIMEOUT) as resp: return json.loads(resp.read().decode("utf-8")) def create_task(): payload = dict( clientKey=API_KEY, task=dict( type="TurnstileTokenTask", # confirm exact type in OMOCaptcha docs websiteURL="https://example.com/login", websiteKey="0x4AAAAAAAxxxxxxxxxxxx", ), ) data = post_json("/createTask", payload) if data<>errorId"] != 0: raise RuntimeError("createTask failed: " + str(data.get("errorDescription"))) return data<>taskId"] def get_result(task_id): payload = dict(clientKey=API_KEY, taskId=task_id) delay = 3 for _ in range(20): # up to about a minute with backoff data = post_json("/getTaskResult", payload) if data<>errorId"] != 0: raise RuntimeError("getTaskResult error: " + str(data.get("errorDescription"))) status = data<>status"] if status == "ready": return data<>solution"]<>token"] if status == "fail": raise RuntimeError("Task failed to solve") time.sleep(delay) delay = min(delay + 2, 10) # polite backoff, cap at 10s raise TimeoutError("Turnstile task did not complete in time") if __name__ == "__main__": task_id = create_task() token = get_result(task_id) print("cf-turnstile-response =", token) Why OMOCaptcha Is a Reliable Captcha Solver for Turnstile OMOCaptcha is AI-only, so there is no human-farm queue delay: it averages 0.42s solve time with up to 99% accuracy across 14 captcha systems. Turnstile is supported alongside reCAPTCHA, hCaptcha, GeeTest, FunCaptcha, and more, all through one endpoint and six SDKs (Python, Node.js, PHP, Java, .NET, Go). Every task is locked to the key that created it, and captcha content is never stored or logged. Comparing options? See our best captcha solving service (https://blog.omocaptcha.com/best-captcha-solving-service-2026) roundup, the captcha solver API pricing (https://blog.omocaptcha.com/captcha-solver-api-pricing) breakdown, and the captcha API quickstart (https://blog.omocaptcha.com/captcha-solver-api-quickstart) if this is your first integration. Solving other widgets? We also cover how to solve reCAPTCHA (https://blog.omocaptcha.com/how-to-solve-recaptcha) and how to solve hCaptcha (https://blog.omocaptcha.com/how-to-solve-hcaptcha). Responsible use Solve Turnstile only where you are authorized to automate: QA and regression testing of your own forms, accessibility tooling, monitoring and uptime checks, load testing, and authorized or contracted data collection. Respect each site's robots.txt, Terms of Service, and rate limits. Do not use a solver for fraud, mass fake-account creation, or ban evasion. Keeping automation legitimate protects your infrastructure and your reputation. FAQ What is the cf-turnstile-response field? It is the hidden input Turnstile writes its token into. When the widget succeeds, the browser posts cf-turnstile-response with the form; your automation must supply a valid turnstile token in that field for verification to pass. Is a Turnstile solver the same as a Cloudflare bypass? No. A Turnstile solver returns a token for a specific widget on a specific page. The full Cloudflare interstitial challenge issues a cf_clearance cookie instead and is solved differently. A "turnstile bypass API" only handles the widget token, not site-wide challenge cookies. Where do I find the sitekey? Inspect the page for a data-sitekey attribute (it starts with 0x...) on the cf-turnstile element, or look at the turnstile.render() call in the page's JavaScript. Pass that value as websiteKey. How long does a token stay valid? Turnstile tokens are short-lived, typically usable for a couple of minutes and only once. Request the token immediately before you submit the form, not far in advance. What does it cost? Turnstile is supported on OMOCaptcha, with token captchas starting from $0.27/1000. See the full pricing page (https://omocaptcha.com/en#pricing) for the current per-captcha rates. Get started with 1000 free solves Sign up and get 1000 free solves to test the Turnstile flow end to end, plus a full refund if your success rate ever drops below 95%. Questions? Email support@omocaptcha.com (24/7). Start now at OMOCaptcha (https://omocaptcha.com/en?utm_source=blog&utm_medium=organic) and drop your first turnstile token into cf-turnstile-response in minutes.