Solver Cloudflare

Cloudflare Challenge

Cloudflare Challenge (also known as the "5-second shield", "Just a moment..." interstitial, or Cloudflare Under Attack mode) is an interactive or background verification flow protecting websites against bots and DDoS attacks.

SolverCF can solve Cloudflare Challenges and return either:

  1. Clearance Cookie (cf_clearance): Use this cookie alongside the matching User-Agent and proxy to bypass Cloudflare protection in HTTP client scrapers (requests, axios, etc.).
  2. Challenge Token: Used when interacting with Cloudflare Turnstile Challenge APIs.

Task Object Parameters

When creating a Cloudflare Challenge task via createTask, pass the following parameters:

Field Type Required Description
type string Yes Must be "TurnstileTask".
websiteUrl string Yes The full URL of the page protected by Cloudflare Challenge (https://...).
websiteKey string Yes The site key extracted from the challenge script (e.g. 0x4AAAAAAAAjq6WYeRDKmebM).
cloudflareTaskType string Yes Set to "cookie" to receive the cf_clearance cookie, or "token" to receive the challenge token.
pageAction string No The action name from the challenge script, typically "interactive".
data string No The cData payload extracted from the page's challenge script.
pageData string No The chlPageData payload extracted from the page's challenge script.
proxy string Required for "cookie" Mandatory when cloudflareTaskType is "cookie" (optional for "token"). Cloudflare binds cf_clearance to the solving IP. Supports HTTP, HTTPS, SOCKS4, SOCKS5. See Supported Proxy Formats below.
userAgent string No Highly recommended. Specific browser User-Agent to solve with. If omitted, SolverCF picks a random User-Agent, but providing your own is strongly recommended to ensure Client Hints consistency.

Caution

Proxy is Mandatory for cf_clearance (cloudflareTaskType: "cookie"): Cloudflare cryptographically binds the cf_clearance cookie to the exact IP address that solved the challenge. When using cloudflareTaskType: "cookie", you MUST provide the proxy that your scraper will use for subsequent requests. If omitted, the cookie will be bound to the solver worker's IP and will be rejected with HTTP 403 Forbidden when you send requests from your machine.

Important

Recommended: Always Pass Your Scraper's userAgent: If userAgent is omitted, SolverCF will randomly assign one. However, you should always provide the exact User-Agent your scraper uses. Cloudflare strictly enforces consistency between User-Agent, Sec-CH-UA, and Sec-CH-UA-Platform. Reusing the same User-Agent and its corresponding Client Hints ensures the highest bypass success rate and avoids 403 Forbidden mismatches.

Supported Proxy Formats

SolverCF supports multiple proxy syntax styles across HTTP, HTTPS, SOCKS4, and SOCKS5:

Format Type Syntax Pattern Example
Standard (No Auth) host:port 103.145.4.12:8080
Standard (With Auth) host:port:user:pass 103.145.4.12:8080:username:password123
URL Format user:pass@host:port username:[email protected]:8080
HTTP / HTTPS Scheme http://[user:pass@]host:port
https://[user:pass@]host:port
http://103.145.4.12:8080
http://username:[email protected]:8080
http://103.145.4.12:8080:username:password123
SOCKS5 Scheme socks5://[user:pass@]host:port socks5://103.145.4.12:1080
socks5://username:[email protected]:1080
socks5://103.145.4.12:1080:username:password123
SOCKS4 Scheme socks4://host:port socks4://103.145.4.12:1080

Note

  • If no protocol scheme is specified, HTTP is used by default.
  • Passwords containing colons (:) or special characters are supported.

Extracting Challenge Data from HTML

On Cloudflare challenge pages, the parameters can be found inside the embedded challenge script:

Html
<script>
  window._cf_chl_opt = {
    cRay: '8b2c123...',
    cType: 'interactive',
    sitekey: '0x4AAAAAAAAjq6WYeRDKmebM',
    cData: 'a35dc237aee2b54e',
    chlPageData: 'iT10BhAtiTDkBgg6...'
  };
</script>
  • websiteKey: sitekey
  • pageAction: cType (usually "interactive")
  • data: cData
  • pageData: chlPageData

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/protected",
    "websiteKey": "0x4AAAAAAAAjq6WYeRDKmebM",
    "cloudflareTaskType": "cookie",
    "pageAction": "interactive",
    "data": "a35dc237aee2b54e",
    "pageData": "iT10BhAtiTDkBgg6EA3TToiOS1BkToaHrutxPzsFrOg...",
    "proxy": "203.0.113.10:8080:user:pass"
  }
}

Response:

JSON
{
  "errorId": 0,
  "taskId": "a1b2c3d4-e5f6-7a8b-9c0d-1e2f3a4b5c6d",
  "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": "a1b2c3d4-e5f6-7a8b-9c0d-1e2f3a4b5c6d"
}

When solved, status becomes "ready":

JSON
{
  "errorId": 0,
  "taskId": "a1b2c3d4-e5f6-7a8b-9c0d-1e2f3a4b5c6d",
  "status": "ready",
  "cost": 0.0009,
  "solution": {
    "type": "TurnstileTask",
    "cookie": "cf_clearance=E4r8...; path=/; domain=.example.com; Secure; HttpOnly; SameSite=None",
    "token": null,
    "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36",
    "secChUa": "\"Chromium\";v=\"124\", \"Google Chrome\";v=\"124\", \"Not-A.Brand\";v=\"99\"",
    "secChUaMobile": "?0",
    "secChUaPlatform": "\"Windows\""
  }
}

Solution Object Properties

Field Type Description
type string Task type (TurnstileTask).
cookie string The cf_clearance cookie string (when cloudflareTaskType is "cookie").
token string Cloudflare Turnstile token (when cloudflareTaskType is "token").
userAgent string Exact User-Agent string used by the worker to solve the challenge. Must be attached to all subsequent HTTP requests.
secChUa string Formatted Sec-CH-UA HTTP Client Hint header (e.g. "Chromium";v="124", "Google Chrome";v="124", "Not-A.Brand";v="99").
secChUaMobile string Sec-CH-UA-Mobile HTTP Client Hint header (?0 for desktop, ?1 for mobile).
secChUaPlatform string Sec-CH-UA-Platform HTTP Client Hint header (e.g. "Windows", "macOS", "Linux").

Tip

Client Hints Included Automatically: SolverCF provides secChUa, secChUaMobile, and secChUaPlatform matching the exact solving environment. When sending requests with cf_clearance, you can directly pass these values into your HTTP client headers without having to construct or parse them yourself.

Crucial Rules for Using cf_clearance:

  1. Same IP / Proxy: You must make subsequent requests using the exact same proxy/IP address provided when creating the task.
  2. Same User-Agent & Client Hints: Send User-Agent (solution.userAgent) along with Sec-CH-UA (solution.secChUa), Sec-CH-UA-Mobile (solution.secChUaMobile), and Sec-CH-UA-Platform (solution.secChUaPlatform) for maximum bypass reliability.

Complete Code Examples

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/protected",
      "websiteKey": "0x4AAAAAAAAjq6WYeRDKmebM",
      "cloudflareTaskType": "cookie",
      "pageAction": "interactive",
      "proxy": "203.0.113.10:8080:user:pass"
    }
  }'

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/protected"
WEBSITE_KEY = "0x4AAAAAAAAjq6WYeRDKmebM"
PROXY = "203.0.113.10:8080:user:pass"

def solve_cloudflare_challenge(client_key: str, website_url: str, website_key: str, proxy: str = None, task_type: str = "cookie"):
    # 1. Create task
    payload = {
        "clientKey": client_key,
        "task": {
            "type": "TurnstileTask",
            "websiteUrl": website_url,
            "websiteKey": website_key,
            "cloudflareTaskType": task_type,
            "pageAction": "interactive",
        }
    }
    if proxy:
        payload["task"]["proxy"] = proxy

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

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

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

        status = res.get("status")
        if status == "ready":
            solution = res["solution"]
            print("Challenge bypassed successfully!")
            print(f"Cookie: {solution.get('cookie')}")
            print(f"UserAgent: {solution.get('userAgent')}")
            return solution

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

    raise TimeoutError("Solving Cloudflare Challenge timed out")

if __name__ == "__main__":
    result = solve_cloudflare_challenge(CLIENT_KEY, WEBSITE_URL, WEBSITE_KEY, proxy=PROXY, task_type="cookie")

Node.js

JavaScript
const CLIENT_KEY = "YOUR_CLIENT_KEY";
const WEBSITE_URL = "https://example.com/protected";
const WEBSITE_KEY = "0x4AAAAAAAAjq6WYeRDKmebM";
const PROXY = "203.0.113.10:8080:user:pass";

async function solveCloudflareChallenge(clientKey, websiteUrl, websiteKey, proxy = null, taskType = "cookie") {
  // 1. Create task
  const createRes = await fetch("https://solvercf.com/token/extension/createTask", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({
      clientKey,
      task: {
        type: "TurnstileTask",
        websiteUrl,
        websiteKey,
        cloudflareTaskType: taskType,
        pageAction: "interactive",
        ...(proxy ? { proxy } : {}),
      },
    }),
  }).then((r) => r.json());

  if (createRes.errorId === 1) {
    throw new Error(`Create task failed: ${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("Challenge solved!");
      return resultRes.solution;
    }

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

  throw new Error("Timeout waiting for challenge solution");
}

solveCloudflareChallenge(CLIENT_KEY, WEBSITE_URL, WEBSITE_KEY, PROXY, "cookie")
  .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/protected";
    private const string WebsiteKey = "0x4AAAAAAAAjq6WYeRDKmebM";
    private const string Proxy = "203.0.113.10:8080:user:pass";

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

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

        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 ChallengeSolution
                {
                    Cookie = solutionElement.TryGetProperty("cookie", out var c) ? c.GetString() : null,
                    Token = solutionElement.TryGetProperty("token", out var t) ? t.GetString() : null,
                    UserAgent = solutionElement.GetProperty("userAgent").GetString(),
                    SecChUa = solutionElement.TryGetProperty("secChUa", out var ua) ? ua.GetString() : null,
                    SecChUaMobile = solutionElement.TryGetProperty("secChUaMobile", out var uam) ? uam.GetString() : null,
                    SecChUaPlatform = solutionElement.TryGetProperty("secChUaPlatform", out var uap) ? uap.GetString() : null,
                };
            }

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

        throw new TimeoutException("Solving Cloudflare Challenge timed out");
    }

    public class ChallengeSolution
    {
        public string? Cookie { get; set; }
        public string? Token { get; set; }
        public string? UserAgent { get; set; }
        public string? SecChUa { get; set; }
        public string? SecChUaMobile { get; set; }
        public string? SecChUaPlatform { get; set; }
    }
}

Depending on whether you set cloudflareTaskType to "cookie" or "token":

Caution

Mandatory Rule: You MUST dispatch subsequent requests using the identical User-Agent (solution.userAgent) and through the identical Proxy / IP provided during createTask. Cloudflare actively blocks requests with mismatched fingerprints with an HTTP 403 Forbidden.

  • Python (curl_cffi): Use curl_cffi.requests to bypass Cloudflare TLS fingerprinting:
    Python
    from curl_cffi import requests
    
    headers = {
        "User-Agent": solution["userAgent"],
        "Cookie": solution["cookie"] # e.g. cf_clearance=...
    }
    # Attach Client Hints if provided in the solution
    if solution.get("secChUa"):
        headers["Sec-CH-UA"] = solution["secChUa"]
        headers["Sec-CH-UA-Mobile"] = solution.get("secChUaMobile", "?0")
        headers["Sec-CH-UA-Platform"] = solution.get("secChUaPlatform", '"Windows"')
    
    proxies = {"http": proxy_url, "https": proxy_url}
    res = requests.get("https://protected-site.com", headers=headers, proxies=proxies, impersonate="chrome124")
    
  • Node.js: Attach Cookie, User-Agent, and the secChUa* headers returned in solution into got-scraping or axios.
  • C#: Add the clearance cookie to a CookieContainer and assign User-Agent along with the matching Sec-CH-UA headers on HttpClient.

2. When receiving the Turnstile Token:

Inject the token into the DOM hidden input or transmit it inside your API payload as you would with standard Turnstile widgets.

👉 For full code implementations across all supported platforms, see: Token & Cookie Integration Guide.