When Cloudflare flags a visitor as suspicious, it serves an interstitial challenge page. Once solved, the browser receives a cf_clearance cookie that grants access for the session. This guide explains how the challenge flow works and how CaptchaAI handles it.
How Cloudflare Challenge pages work
- User requests a Cloudflare-protected page
- Cloudflare evaluates risk signals (IP reputation, headers, TLS fingerprint)
- If flagged, Cloudflare returns a 403 or 503 with a JavaScript challenge page
- The challenge page runs browser checks and may present a Turnstile widget
- On success, Cloudflare sets
cf_clearanceand redirects to the original URL - Subsequent requests with the cookie pass through without challenge
The cf_clearance cookie
| Property | Details |
|---|---|
| Name | cf_clearance |
| Domain | Target site domain (e.g., .example.com) |
| Path | / |
| Lifetime | Typically 30 minutes to 24 hours |
| HttpOnly | Yes |
| Secure | Yes (HTTPS only) |
| SameSite | None |
The cookie is tied to several factors:
- IP address — Using the cookie from a different IP usually fails
- User-Agent — Must match the UA used during challenge solving
- TLS fingerprint — Some configurations bind to the TLS ClientHello
Challenge types
Cloudflare serves different challenge levels:
| Challenge | Response code | User interaction | Description |
|---|---|---|---|
| JS Challenge | 503 | None | JavaScript execution only |
| Managed Challenge | 403 | Maybe | Cloudflare decides — may show Turnstile or pass silently |
| Interactive Challenge | 403 | Yes | Always shows a Turnstile widget |
CaptchaAI solves all three types through the Cloudflare Challenge solver.
Solving with CaptchaAI
Python
import requests
import time
API_KEY = "YOUR_API_KEY"
TARGET_URL = "https://example.com/protected-page"
# Submit Cloudflare Challenge task
resp = requests.post("https://ocr.captchaai.com/in.php", data={
"key": API_KEY,
"method": "turnstile",
"sitekey": "0x0000000000000000000000", # may be generic for CF challenge
"pageurl": TARGET_URL,
"json": "1",
}).json()
if resp["status"] != 1:
raise Exception(f"Submit error: {resp['request']}")
task_id = resp["request"]
print(f"Task ID: {task_id}")
# Poll for result
for _ in range(30):
time.sleep(5)
result = requests.get("https://ocr.captchaai.com/res.php", params={
"key": API_KEY, "action": "get", "id": task_id, "json": "1"
}).json()
if result["status"] == 1:
token = result["request"]
print(f"Token received: {token[:50]}...")
break
if result["request"] != "CAPCHA_NOT_READY":
raise Exception(f"Error: {result['request']}")
JavaScript
const axios = require('axios');
const API_KEY = 'YOUR_API_KEY';
const TARGET_URL = 'https://example.com/protected-page';
const submit = await axios.post('https://ocr.captchaai.com/in.php', null, {
params: {
key: API_KEY,
method: 'turnstile',
sitekey: '0x0000000000000000000000',
pageurl: TARGET_URL,
json: 1,
}
});
const taskId = submit.data.request;
// Poll
let token = null;
for (let i = 0; i < 30; i++) {
await new Promise(r => setTimeout(r, 5000));
const poll = await axios.get('https://ocr.captchaai.com/res.php', {
params: { key: API_KEY, action: 'get', id: taskId, json: 1 }
});
if (poll.data.status === 1) {
token = poll.data.request;
break;
}
}
console.log(`Token: ${token.substring(0, 50)}...`);
Using the solved token
After solving, inject the token into the challenge page to obtain cf_clearance:
# With Selenium
from selenium import webdriver
driver = webdriver.Chrome()
driver.get(TARGET_URL) # Load the challenge page
# Inject token into Turnstile response field
driver.execute_script("""
const input = document.querySelector('input[name="cf-turnstile-response"]');
if (input) input.value = arguments[0];
// Trigger form submit or callback
const form = document.querySelector('form');
if (form) form.submit();
""", token)
# Wait for redirect and extract cookies
import time
time.sleep(3)
cookies = driver.get_cookies()
cf_clearance = next(
(c for c in cookies if c['name'] == 'cf_clearance'), None
)
if cf_clearance:
print(f"cf_clearance: {cf_clearance['value'][:30]}...")
Reusing the cookie
session = requests.Session()
session.cookies.set("cf_clearance", cf_clearance["value"], domain=".example.com")
session.headers.update({
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
})
# Now access protected pages
resp = session.get("https://example.com/api/data")
print(resp.status_code) # 200
Cookie lifetime and refresh
The cf_clearance cookie expires. Plan for re-solving:
import datetime
def is_cookie_valid(cookie):
if not cookie:
return False
expiry = cookie.get("expiry", 0)
return datetime.datetime.now().timestamp() < expiry - 60 # 60s buffer
def get_or_refresh_clearance(driver, target_url, solve_func):
cookies = driver.get_cookies()
cf = next((c for c in cookies if c["name"] == "cf_clearance"), None)
if is_cookie_valid(cf):
return cf["value"]
# Re-solve
token = solve_func(target_url)
# ... inject and extract new cookie
Troubleshooting
| Problem | Cause | Fix |
|---|---|---|
| Cookie rejected after solving | IP mismatch | Use the same proxy for solving and requests |
| Cookie expires quickly | Short TTL set by site | Re-solve before expiry; check expiry field |
| 403 despite valid cookie | User-Agent mismatch | Match UA between solve and request sessions |
| Challenge page not loading | JavaScript disabled | Use a full browser (Selenium, Puppeteer) |
FAQ
Can I share cf_clearance between different machines?
Only if they share the same IP and you match the User-Agent string. Cloudflare often ties the cookie to the originating IP.
How long does cf_clearance last?
Typically 30 minutes to 24 hours, depending on the site owner's Cloudflare configuration.
Solve Cloudflare Challenge pages with CaptchaAI
Get your API key at captchaai.com.
Discussions (0)
Join the conversation
Sign in to share your opinion.
Sign InNo comments yet.