Solver Cloudflare

Cloudflare Turnstile

Cloudflare Turnstile is a smart, privacy-first CAPTCHA alternative designed to verify that visitors are real humans without presenting interactive puzzle challenges.

SolverCF allows you to solve both managed and non-interactive/invisible Cloudflare Turnstile widgets automatically.


Task Object Parameters

When creating a Turnstile task via createTask, pass the following parameters in the task object:

Field Type Required Description
type string Yes Must be "TurnstileTask".
websiteUrl string Yes The full URL of the page containing the Turnstile widget (https://...).
websiteKey string Yes The Turnstile site key extracted from the target page (starts with 0x4).
userAgent string No Specific browser User-Agent to solve with. If omitted, SolverCF uses a high-reputation default browser User-Agent.
proxy string No Optional proxy in host:port or host:port:user:pass format.

Finding the Site Key

You can find the Turnstile websiteKey by inspecting the page source or DOM:

  • Look for an element with data-sitekey:
    Html
    <div class="cf-turnstile" data-sitekey="0x4AAAAAAAB__YGWiObopXheP"></div>
    
  • Or search page scripts for calls to turnstile.render:
    JavaScript
    turnstile.render('#container', { sitekey: '0x4AAAAAAAB__YGWiObopXheP' });
    

API Workflow

Step 1: Create Task

Send a POST request to https://solvercf.com/token/extension/createTask:

JSON
{
  "clientKey": "YOUR_CLIENT_KEY",
  "task": {
    "type": "TurnstileTask",
    "websiteUrl": "https://example.com/login",
    "websiteKey": "0x4AAAAAAAB__YGWiObopXheP"
  }
}

Response:

JSON
{
  "errorId": 0,
  "taskId": "7f8b9c2a-3d4e-5f6a-7b8c-9d0e1f2a3b4c",
  "status": "created"
}

Step 2: Poll Task Result

Send periodic POST requests (every 1.5s) to https://solvercf.com/token/extension/getTaskResult:

JSON
{
  "clientKey": "YOUR_CLIENT_KEY",
  "taskId": "7f8b9c2a-3d4e-5f6a-7b8c-9d0e1f2a3b4c"
}

When solved, status becomes "ready":

JSON
{
  "errorId": 0,
  "taskId": "7f8b9c2a-3d4e-5f6a-7b8c-9d0e1f2a3b4c",
  "status": "ready",
  "cost": 0.0009,
  "solution": {
    "type": "TurnstileTask",
    "token": "0.4AAAAAAAB__YGWiObopXheP_abcdef123456...",
    "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36"
  }
}

Important: Always submit the solved solution.token to the target website alongside the exact solution.userAgent returned by SolverCF. Cloudflare validates that the token originates from the matching User-Agent.


Complete Code Examples

Below are ready-to-run code examples that submit the task, poll for the result, and return the solved token.

cURL

Step 1: Create Task

cURL
curl -X POST https://solvercf.com/token/extension/createTask \
  -H "Content-Type: application/json" \
  -d '{
    "clientKey": "YOUR_CLIENT_KEY",
    "task": {
      "type": "TurnstileTask",
      "websiteUrl": "https://example.com/login",
      "websiteKey": "0x4AAAAAAAB__YGWiObopXheP"
    }
  }'

Step 2: Get Task Result

cURL
curl -X POST https://solvercf.com/token/extension/getTaskResult \
  -H "Content-Type: application/json" \
  -d '{
    "clientKey": "YOUR_CLIENT_KEY",
    "taskId": "YOUR_TASK_ID_FROM_STEP_1"
  }'

Python

Python
import time
import requests

CLIENT_KEY = "YOUR_CLIENT_KEY"
WEBSITE_URL = "https://example.com/login"
WEBSITE_KEY = "0x4AAAAAAAB__YGWiObopXheP"

def solve_turnstile(client_key: str, website_url: str, website_key: str, proxy: str = None, user_agent: str = None):
    # 1. Create task
    payload = {
        "clientKey": client_key,
        "task": {
            "type": "TurnstileTask",
            "websiteUrl": website_url,
            "websiteKey": website_key,
        }
    }
    if proxy:
        payload["task"]["proxy"] = proxy
    if user_agent:
        payload["task"]["userAgent"] = user_agent

    create_resp = requests.post("https://solvercf.com/token/extension/createTask", json=payload).json()
    if create_resp.get("errorId") == 1:
        raise Exception(f"Failed to create task: {create_resp.get('errorDescription')}")

    task_id = create_resp["taskId"]
    print(f"Task created: {task_id}")

    # 2. Poll result
    timeout = 90
    start_time = time.time()
    while time.time() - start_time < timeout:
        time.sleep(1.5)
        result_resp = requests.post("https://solvercf.com/token/extension/getTaskResult", json={
            "clientKey": client_key,
            "taskId": task_id
        }).json()

        status = result_resp.get("status")
        if status == "ready":
            solution = result_resp["solution"]
            print("Turnstile solved successfully!")
            print(f"Token: {solution['token']}")
            print(f"UserAgent: {solution['userAgent']}")
            return solution

        if status in ("failed", "expired"):
            raise Exception(f"Task ended with status: {status}")

    raise TimeoutError("Solving Turnstile timed out")

if __name__ == "__main__":
    result = solve_turnstile(CLIENT_KEY, WEBSITE_URL, WEBSITE_KEY)

Node.js

JavaScript
const CLIENT_KEY = "YOUR_CLIENT_KEY";
const WEBSITE_URL = "https://example.com/login";
const WEBSITE_KEY = "0x4AAAAAAAB__YGWiObopXheP";

async function solveTurnstile(clientKey, websiteUrl, websiteKey, options = {}) {
  // 1. Create task
  const createPayload = {
    clientKey,
    task: {
      type: "TurnstileTask",
      websiteUrl,
      websiteKey,
      ...(options.proxy ? { proxy: options.proxy } : {}),
      ...(options.userAgent ? { userAgent: options.userAgent } : {}),
    },
  };

  const createRes = await fetch("https://solvercf.com/token/extension/createTask", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify(createPayload),
  }).then((r) => r.json());

  if (createRes.errorId === 1) {
    throw new Error(`Failed to create task: ${createRes.errorDescription}`);
  }

  const taskId = createRes.taskId;
  console.log(`Task created: ${taskId}`);

  // 2. Poll result
  const deadline = Date.now() + 90000;
  while (Date.now() < deadline) {
    await new Promise((resolve) => setTimeout(resolve, 1500));

    const resultRes = await fetch("https://solvercf.com/token/extension/getTaskResult", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ clientKey, taskId }),
    }).then((r) => r.json());

    if (resultRes.status === "ready") {
      console.log("Turnstile solved successfully!");
      return resultRes.solution;
    }

    if (resultRes.status === "failed" || resultRes.status === "expired") {
      throw new Error(`Task failed with status: ${resultRes.status}`);
    }
  }

  throw new Error("Solving Turnstile timed out");
}

solveTurnstile(CLIENT_KEY, WEBSITE_URL, WEBSITE_KEY)
  .then((solution) => console.log(solution))
  .catch((err) => console.error(err));

C#

C#
using System;
using System.Net.Http;
using System.Net.Http.Json;
using System.Text.Json;
using System.Threading.Tasks;

class Program
{
    private static readonly HttpClient HttpClient = new HttpClient();
    private const string ClientKey = "YOUR_CLIENT_KEY";
    private const string WebsiteUrl = "https://example.com/login";
    private const string WebsiteKey = "0x4AAAAAAAB__YGWiObopXheP";

    static async Task Main()
    {
        var solution = await SolveTurnstileAsync(ClientKey, WebsiteUrl, WebsiteKey);
        Console.WriteLine($"Token: {solution.Token}");
        Console.WriteLine($"UserAgent: {solution.UserAgent}");
    }

    public static async Task<TurnstileSolution> SolveTurnstileAsync(
        string clientKey,
        string websiteUrl,
        string websiteKey,
        string? proxy = null,
        string? userAgent = null)
    {
        // 1. Create task
        var createResponse = await HttpClient.PostAsJsonAsync("https://solvercf.com/token/extension/createTask", new
        {
            clientKey,
            task = new
            {
                type = "TurnstileTask",
                websiteUrl,
                websiteKey,
                proxy,
                userAgent
            }
        });

        var createJson = await createResponse.Content.ReadFromJsonAsync<JsonElement>();
        if (createJson.TryGetProperty("errorId", out var errorId) && errorId.GetInt32() == 1)
        {
            throw new Exception($"Failed to create task: {createJson.GetProperty("errorDescription").GetString()}");
        }

        string taskId = createJson.GetProperty("taskId").GetString()!;
        Console.WriteLine($"Task created: {taskId}");

        // 2. Poll result
        DateTime deadline = DateTime.UtcNow.AddSeconds(90);
        while (DateTime.UtcNow < deadline)
        {
            await Task.Delay(1500);

            var resultResponse = await HttpClient.PostAsJsonAsync("https://solvercf.com/token/extension/getTaskResult", new
            {
                clientKey,
                taskId
            });

            var resultJson = await resultResponse.Content.ReadFromJsonAsync<JsonElement>();
            string status = resultJson.GetProperty("status").GetString()!;

            if (status == "ready")
            {
                var solutionElement = resultJson.GetProperty("solution");
                return new TurnstileSolution
                {
                    Token = solutionElement.GetProperty("token").GetString(),
                    UserAgent = solutionElement.GetProperty("userAgent").GetString()
                };
            }

            if (status == "failed" || status == "expired")
            {
                throw new Exception($"Task ended with status: {status}");
            }
        }

        throw new TimeoutException("Solving Turnstile timed out");
    }

    public class TurnstileSolution
    {
        public string? Token { get; set; }
        public string? UserAgent { get; set; }
    }
}

Using the Token After Solving (Integration Guide)

Once you retrieve solution.token, integrate it using either of these approaches:

  1. Direct API Submission (Headless HTTP Request): Place the token in your POST request body under the field expected by the target server (typically cf-turnstile-response or turnstile_token), accompanied by the matching User-Agent header.
  2. DOM Injection in Automated Browsers:
    JavaScript
    // Set the token on the hidden input field
    document.querySelector('[name="cf-turnstile-response"]').value = solution.token;
    // Trigger site callback or submit form
    if (window.onTurnstileSuccess) window.onTurnstileSuccess(solution.token);
    document.querySelector('form').submit();
    

👉 For complete multi-language code examples (Python curl_cffi, Node.js, C#, Playwright, Selenium), see: Token & Cookie Integration Guide.