Cloudflare Turnstile Solver: How to Bypass Turnstile CAPTCHA

How to solve Cloudflare Turnstile challenges programmatically. Includes Python and Node.js examples with Playwright integration.

March 16, 2026 · 4 min read

Cloudflare Turnstile is the newest generation of CAPTCHA from Cloudflare. It's replacing hCaptcha on many sites and is designed to be privacy-friendly while still blocking bots. This guide shows you how to solve it via API.

What is Cloudflare Turnstile?

Turnstile is an invisible CAPTCHA that runs browser fingerprinting and behavioral analysis in the background. Unlike reCAPTCHA v2, users rarely see a challenge — but bots and automation tools are blocked unless they can produce a valid token.

You need:

Finding the Turnstile sitekey

<!-- Look for this in the page source -->
<div class="cf-turnstile" data-sitekey="0x4AAAAAAAxxxxxx"></div>

Solving Turnstile with Ocilar

cURL

curl -X POST https://api.ocilar.com/api/v1/solve/turnstile \
  -H "X-API-Key: sk-your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "sitekey": "0x4AAAAAAAxxxxxx",
    "url": "https://example.com/login"
  }'

# Response
{"token":"0.AbCdEf...","latency_ms":2800,"credits_used":1}

Python

from ocilar import OcilarClient

client = OcilarClient(api_key="sk-your_key")

result = client.solve_turnstile(
    sitekey="0x4AAAAAAAxxxxxx",
    url="https://example.com/login"
)

print(result.token)  # "0.AbCdEf..."

Node.js

import { OcilarClient } from '@ocilar/sdk'

const client = new OcilarClient({ apiKey: 'sk-your_key' })

const { token } = await client.solveTurnstile({
  sitekey: '0x4AAAAAAAxxxxxx',
  url: 'https://example.com/login'
})

console.log(token) // "0.AbCdEf..."

Submitting the token with Playwright

import asyncio
from playwright.async_api import async_playwright
from ocilar import OcilarClient

async def solve_with_turnstile(url: str, sitekey: str):
    client = OcilarClient(api_key="sk-your_key")

    async with async_playwright() as p:
        browser = await p.chromium.launch(headless=True)
        page = await browser.new_page()
        await page.goto(url)

        result = client.solve_turnstile(sitekey=sitekey, url=url)

        await page.evaluate(f'''
            document.querySelector('[name="cf-turnstile-response"]').value = "{result.token}";
        ''')

        await page.click('button[type="submit"]')
        await browser.close()

asyncio.run(solve_with_turnstile("https://example.com/login", "0x4AAAA..."))

Handling Turnstile with raw HTTP requests

import requests
from ocilar import OcilarClient

client = OcilarClient(api_key="sk-your_key")

result = client.solve_turnstile(
    sitekey="0x4AAAAAAAxxxxxx",
    url="https://example.com/login"
)

response = requests.post("https://example.com/login", data={
    "username": "user@example.com",
    "password": "secret",
    "cf-turnstile-response": result.token
})

print(response.status_code)

Pricing

Cloudflare Turnstile costs $0.24 per 1,000 solves — significantly cheaper than competitors.

ServiceTurnstile / 1K
2Captcha$2.99
CapSolver$1.00
Ocilar$0.24

FAQ

How long does Turnstile take to solve?

Average latency is 2–4 seconds. The token is valid for 300 seconds (5 minutes).

Does this work for all Turnstile modes?

Yes. Ocilar handles managed, non-interactive, and invisible modes automatically.

Is there a free tier?

Yes — 1,000 free solves/month. See all plans →

Try Ocilar free

1,000 free solves. No credit card required.

Get API Key