Troubleshooting

Cloudflare Challenge vs Turnstile: How to Detect Which One You Have

Using the wrong CaptchaAI method for Cloudflare protections is one of the most common mistakes. Cloudflare Challenge and Cloudflare Turnstile look similar but are fundamentally different. Sending turnstile when the site uses a full-page challenge — or vice versa — will always fail.


The two Cloudflare protection types

Feature Cloudflare Challenge Cloudflare Turnstile
Type Full-page interstitial Embedded widget
Appearance Blocks the entire page, "Checking your browser" Small checkbox or invisible widget within a form
CaptchaAI method cloudflare_challenge turnstile
Returns cf_clearance cookie Token string
Requires proxy Yes (mandatory) Recommended
Requires User-Agent Yes (mandatory) No

How to identify Cloudflare Challenge

A Cloudflare Challenge is a full-page interstitial that blocks access to the content. You see it before the actual page loads.

Visual signs:

  • "Checking your browser before accessing..." message
  • Cloudflare loading spinner
  • Page title contains "Just a moment..."
  • URL stays the same but content is a Cloudflare page

HTML signs:

<!-- Cloudflare Challenge page indicators -->
<title>Just a moment...</title>
<div id="challenge-running">...</div>
<div class="cf-browser-verification">...</div>

Programmatic detection:

import requests

resp = requests.get("https://example.com")

is_cf_challenge = (
    resp.status_code == 403 and
    "Just a moment" in resp.text or
    "cf-browser-verification" in resp.text or
    "challenge-platform" in resp.text
)

if is_cf_challenge:
    print("Cloudflare Challenge detected — use method: cloudflare_challenge")

How to identify Cloudflare Turnstile

Turnstile is an embedded widget inside a page that already loaded. It appears within forms, like reCAPTCHA.

Visual signs:

  • Small Cloudflare widget within a form (checkbox style)
  • The rest of the page content is visible
  • Widget says "Verify you are human"

HTML signs:

<!-- Turnstile widget indicators -->
<div class="cf-turnstile" data-sitekey="0x4AAAAAAADnPIDROz1234"></div>

<!-- Or loaded via JavaScript -->
<script src="https://challenges.cloudflare.com/turnstile/v0/api.js"></script>

Programmatic detection:

import requests

resp = requests.get("https://example.com/login")

is_turnstile = (
    "cf-turnstile" in resp.text or
    "challenges.cloudflare.com/turnstile" in resp.text
)

if is_turnstile:
    # Extract sitekey
    if 'data-sitekey="' in resp.text:
        start = resp.text.index('data-sitekey="') + 14
        end = resp.text.index('"', start)
        sitekey = resp.text[start:end]
        print(f"Turnstile detected — sitekey: {sitekey}")
        print("Use method: turnstile")

Combined detection function

def detect_cloudflare_type(url):
    """Detect which Cloudflare protection a URL uses."""
    resp = requests.get(url, allow_redirects=True)

    # Check for full-page Challenge
    if resp.status_code in [403, 503]:
        if any(marker in resp.text for marker in [
            "Just a moment",
            "cf-browser-verification",
            "challenge-platform",
            "challenge-running"
        ]):
            return {"type": "cloudflare_challenge", "method": "cloudflare_challenge"}

    # Check for embedded Turnstile
    if "cf-turnstile" in resp.text or "challenges.cloudflare.com/turnstile" in resp.text:
        sitekey = None
        if 'data-sitekey="' in resp.text:
            start = resp.text.index('data-sitekey="') + 14
            end = resp.text.index('"', start)
            sitekey = resp.text[start:end]
        return {"type": "turnstile", "method": "turnstile", "sitekey": sitekey}

    return {"type": "none", "method": None}


# Usage
result = detect_cloudflare_type("https://example.com")
print(f"Protection: {result['type']}")
print(f"CaptchaAI method: {result['method']}")

Solving each type

Cloudflare Challenge:

data = {
    "key": "YOUR_API_KEY",
    "method": "cloudflare_challenge",
    "pageurl": "https://example.com",
    "proxy": "host:port:user:pass",   # MANDATORY
    "proxytype": "HTTP",               # MANDATORY
    "userAgent": "Mozilla/5.0 ...",    # MANDATORY
    "json": 1
}
# Returns cf_clearance cookie — set it in your session

Cloudflare Turnstile:

data = {
    "key": "YOUR_API_KEY",
    "method": "turnstile",
    "sitekey": "0x4AAAAAAADnPIDROz1234",
    "pageurl": "https://example.com/login",
    "json": 1
}
# Returns a token — inject into cf-turnstile-response field

Common mistakes

Mistake Result Fix
Using turnstile for a Challenge page ERROR_CAPTCHA_UNSOLVABLE Switch to cloudflare_challenge
Using cloudflare_challenge for Turnstile Wrong response format Switch to turnstile
No proxy for Challenge ERROR_PROXY_NOT_AUTHORIZED Add proxy — it is mandatory for Challenge
No sitekey for Turnstile ERROR_BAD_PARAMETERS Extract sitekey from the page HTML

FAQ

Can a site use both Challenge and Turnstile?

Yes. A site might use Cloudflare Challenge on initial access and Turnstile within its login form. You need to solve both in sequence.

Why does Challenge require a proxy but Turnstile does not?

Challenge returns a cf_clearance cookie bound to an IP. CaptchaAI must use your proxy to generate a cookie that works from your IP. Turnstile returns an IP-independent token.

What if detection returns "none" but I still see Cloudflare?

Some Cloudflare protections only trigger on specific actions (POST requests, API calls) or for certain User-Agents. Try accessing the URL with a bot-like User-Agent to trigger the challenge.


Solve Cloudflare CAPTCHAs with CaptchaAI

Handle both Challenge and Turnstile at captchaai.com.


Discussions (0)

No comments yet.