Вернулся 503 без единого видимого элемента на странице? Это, скорее всего, Managed Challenge — он уже пропустил запрос невидимо. Пришёл 403 с полноэкранным виджетом? Это Interactive Challenge, устаревшее действие, которое требует взаимодействия всегда. Разница определяет и то, что увидит посетитель, и какой метод CaptchaAI вызывать: turnstile для видимого виджета или cloudflare_challenge для полностраничной JS-проверки. Коротко о том, что меняется, если сайт вот-вот перейдёт с одного типа на другой:
- Interactive → Managed: запрос может начать проходить невидимо (шанс ~90%).
- HTTP 403 → 503: обновите проверку кода ответа в своём коде.
- Всегда видимый виджет → адаптивный: он может вовсе отсутствовать в HTML.
- Sitekey не меняется, код решения CaptchaAI остаётся прежним.
qa_validation_cookieтот же — логика обработки cookie не меняется.
Чем управляемый вызов отличается от интерактивного
| Параметр | Managed Challenge | Interactive Challenge |
|---|---|---|
| Появился | 2021 год | До 2021 года (наследие) |
| Адаптивный? | Да — Cloudflare оценивает каждый визит отдельно | Нет — всегда интерактивен |
| Возможно невидимое прохождение? | Да, ~90% посетителей проходят незаметно | Нет, CAPTCHA показывается всегда |
| Какие проверки задействует | Невидимая проверка → Turnstile → JS-задача | Всегда видимая CAPTCHA |
| Рекомендован Cloudflare? | Да, вариант по умолчанию для новых правил | Нет, оставлен для обратной совместимости |
| Трение для пользователя | Низкое — большинство ничего не замечает | Высокое — взаимодействие обязательно |
| HTTP-статус | 503 | 403 |
| Метод CaptchaAI | turnstile или cloudflare_challenge |
turnstile |
Что важно запомнить в первую очередь:
- Managed Challenge — вариант по умолчанию для новых WAF-правил, Interactive Challenge — наследие для обратной совместимости.
- HTTP-статус сразу подсказывает тип: 503 значит Managed, 403 значит Interactive.
- Оба варианта решаются через CaptchaAI, разница только в методе API.
Как работает Managed Challenge изнутри
Managed Challenge — рекомендуемое действие Cloudflare для новых WAF-правил. Вместо того чтобы показывать CAPTCHA каждому подряд, Cloudflare оценивает сигналы конкретного визита и подбирает наименее навязчивую проверку.
Ключевая мысль: сложность проверки подбирается динамически, поэтому один и тот же маршрут может в разные заходы выглядеть по-разному в логах.
Логика принятия решения
WAF rule triggers Managed Challenge
↓
Cloudflare evaluates visitor signals:
├─ Browser сигналы браузера quality
├─ IP reputation score
├─ TLS сигналы браузера (JA3/JA4)
├─ Request history
├─ Behavioral signals
└─ Device capabilities
↓
Risk assessment → Challenge level selected:
├─ LOW risk → Invisible pass (no visible UI)
├─ MEDIUM risk → Non-interactive Turnstile (background PoW)
├─ HIGH risk → Interactive Turnstile (checkbox/widget)
└─ VERY HIGH risk → JavaScript challenge page (5s wait)
↓
Challenge completed
↓
qa_validation_cookie cookie issued
Что видит посетитель — по уровню риска
- Обычный браузер, чистый IP — ничего не видно, прохождение полностью невидимое (~90% посетителей).
- Новый браузер, нейтральный IP — короткий спиннер на экране (~5%).
- Подозрительные сигналы — чекбокс Cloudflare Turnstile (~4%).
- Сигналы высокого риска — страница «Проверка браузера…» (~1%).
HTML управляемого вызова
Страницы Managed Challenge используют платформу проверок Cloudflare:
<!-- Managed Challenge page (when visible) -->
<body>
<div id="challenge-stage">
<div id="challenge-body-text">
Verifying you are human. This may take a few seconds.
</div>
<!-- Turnstile widget (when rendered) -->
<div class="cf-turnstile"
data-sitekey="0x4AAAAAAAC3DHQhMMQ_Rxrg">
</div>
</div>
<!-- Challenge platform script -->
<script src="/cdn-cgi/challenge-platform/h/g/orchestrate/managed/v1?ray=...">
</script>
</body>
Подсказка:
sitekeyдля Turnstile-виджета лежит в атрибутеdata-sitekey— его можно вытащить регуляркой, не поднимая полноценный браузер.
Interactive Challenge: вызов без исключений
Interactive Challenge не оценивает риск конкретного визита — каждый посетитель видит полноэкранную CAPTCHA и обязан пройти её. Невидимого прохождения здесь не предусмотрено в принципе.
Два факта, которые стоит держать в голове при автоматизации именно этого варианта:
- сайт может использовать его выборочно, только для отдельных маршрутов WAF-правил;
- код решения не отличается от Managed Challenge — тот же метод
turnstile, другой лишь код ответа.
Как это работает
WAF rule triggers Interactive Challenge
↓
Full-page CAPTCHA served (HTTP 403)
↓
Visitor must interact with CAPTCHA widget
↓
CAPTCHA solved
↓
qa_validation_cookie cookie issued
Единственный сценарий для посетителя
Каждый посетитель видит полностраничную задачу с виджетом, похожим на Turnstile:
<!-- Interactive Challenge page -->
<body>
<div id="challenge-running">
<div class="main-wrapper">
<h2>Please verify you are human</h2>
<!-- Always-visible challenge widget -->
<div class="challenge-widget">
<!-- Checkbox + verification -->
</div>
</div>
</div>
</body>
Подсказка: разметка почти повторяет Managed Challenge, но виджет
challenge-widgetрендерится всегда, а не по результату оценки риска.
Почему Cloudflare не рекомендует его для новых правил
- Виден всегда — 100% посетителей видят проверку.
- Больше трения — взаимодействие обязательно для каждого.
- Выше показатель отказов — часть пользователей уходит, не пройдя проверку.
- Нет адаптации к риску — даже доверенные посетители проходят её.
- Проблемы доступности — взаимодействие обязательно для всех без исключения.
Как определить тип вызова по ответу сервера
Прежде чем выбирать метод CaptchaAI, разберитесь, что именно вернул сервер, — без доступа к панели Cloudflare это единственный надёжный способ. Следующая функция классифицирует ответ по HTTP-статусу и содержимому страницы:
import requests
import re
def identify_challenge_type(url):
"""Determine if a URL uses Managed or Interactive Challenge."""
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
"AppleWebKit/537.36 Chrome/120.0.0.0",
"Accept": "text/html,*/*;q=0.8",
"Accept-Language": "en-US,en;q=0.9",
}
response = requests.get(url, headers=headers, timeout=15, allow_redirects=False)
html = response.text
status = response.status_code
result = {
"url": url,
"status": status,
"challenge_type": None,
"cf_ray": response.headers.get("cf-ray", ""),
"solve_method": None,
}
if status == 200:
# Check for inline Turnstile widget (not a challenge page)
if "cf-turnstile" in html:
result["challenge_type"] = "turnstile_widget"
result["solve_method"] = "turnstile"
else:
result["challenge_type"] = "none"
return result
if status == 503:
# 503 indicates Managed Challenge or IUAM
if "managed" in html or "challenge-platform" in html:
result["challenge_type"] = "managed_challenge"
result["solve_method"] = "turnstile" # Managed renders as Turnstile
elif "jschl" in html:
result["challenge_type"] = "iuam_js_challenge"
result["solve_method"] = "turnstile"
else:
result["challenge_type"] = "unknown_503"
return result
if status == 403:
if "challenge" in html.lower():
result["challenge_type"] = "interactive_challenge"
result["solve_method"] = "turnstile"
else:
result["challenge_type"] = "waf_block"
result["solve_method"] = None # Hard block, not solvable
return result
return result
# Usage
info = identify_challenge_type("https://protected-site.com/login")
print(f"Challenge: {info['challenge_type']}")
print(f"Solve with: {info['solve_method']}")
Сигналы для быстрой диагностики
Четыре типа ответа различаются по сочетанию признаков:
- Managed Challenge — HTTP 503, в HTML есть
challenge-platform, путьmanagedв скрипте, невидимое прохождение возможно. - Interactive Challenge — HTTP 403, в HTML есть
challenge-platform, виджет виден всегда, невидимого прохождения не бывает. - IUAM (устаревшая JS-проверка) — HTTP 503, в HTML есть
jschl, безchallenge-platformи безmanaged. - Блок WAF — HTTP 403 без единого признака проверки: это не вызов, а жёсткая блокировка.
Как решать оба типа через API CaptchaAI
Managed Challenge: какой метод вызвать
Managed Challenge почти всегда рендерится как виджет Turnstile — вызывайте метод turnstile. Если видимого виджета на странице нет, значит проверка ушла на JS-уровень, и нужен cloudflare_challenge:
import requests
import time
API_KEY = "YOUR_API_KEY"
def solve_managed_challenge(url, sitekey=None):
"""Solve Cloudflare Managed Challenge."""
# If sitekey not provided, extract from page
if not sitekey:
import re
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
"AppleWebKit/537.36 Chrome/120.0.0.0",
}
page = requests.get(url, headers=headers, timeout=15)
match = re.search(
r'data-sitekey=["\']([0-9x][A-Za-z0-9_-]+)["\']', page.text
)
sitekey = match.group(1) if match else None
if not sitekey:
# No visible Turnstile — try turnstile method
return solve_js_challenge(url)
submit = requests.post("https://ocr.captchaai.com/in.php", data={
"key": API_KEY,
"method": "turnstile",
"sitekey": sitekey,
"pageurl": url,
"json": 1,
})
task_id = submit.json()["request"]
for _ in range(60):
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.get("status") == 1:
return result["request"]
raise TimeoutError("Solve timed out")
def solve_js_challenge(url):
"""Fallback to turnstile method."""
submit = requests.post("https://ocr.captchaai.com/in.php", data={
"key": API_KEY,
"method": "turnstile",
"sitekey": "managed",
"pageurl": url,
"json": 1,
})
task_id = submit.json()["request"]
for _ in range(60):
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.get("status") == 1:
return result["request"]
raise TimeoutError("Solve timed out")
Подсказка: оба вызова опрашивают
res.phpодним и тем же циклом — отдельная логика ретраев под каждый тип не нужна.
Interactive Challenge: тот же виджет, тот же метод
Interactive Challenge всегда показывает виджет, похожий на Turnstile, поэтому здесь тоже подходит метод turnstile:
def solve_interactive_challenge(url, sitekey):
"""Solve Cloudflare Interactive Challenge (legacy)."""
submit = requests.post("https://ocr.captchaai.com/in.php", data={
"key": API_KEY,
"method": "turnstile",
"sitekey": sitekey,
"pageurl": url,
"json": 1,
})
task_id = submit.json()["request"]
for _ in range(60):
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.get("status") == 1:
return result["request"]
raise TimeoutError("Solve timed out")
Итого для Python: одна и та же пара «отправить → опросить» покрывает оба типа вызова, различается только значение method.
Пример на Node.js для обоих сценариев
const axios = require("axios");
const API_KEY = "YOUR_API_KEY";
async function solveCloudflareChallenge(url, type = "managed") {
const method = type === "js_challenge" ? "turnstile" : "turnstile";
const sitekey =
type === "js_challenge" ? "managed" : await extractSitekey(url);
const submit = await axios.post("https://ocr.captchaai.com/in.php", null, {
params: {
key: API_KEY,
method,
sitekey: sitekey || "managed",
pageurl: url,
json: 1,
},
});
const taskId = submit.data.request;
for (let i = 0; i < 60; i++) {
await new Promise((r) => setTimeout(r, 5000));
const result = await axios.get("https://ocr.captchaai.com/res.php", {
params: { key: API_KEY, action: "get", id: taskId, json: 1 },
});
if (result.data.status === 1) {
return result.data.request;
}
}
throw new Error("Solve timed out");
}
async function extractSitekey(url) {
try {
const response = await axios.get(url, {
headers: { "User-Agent": "Mozilla/5.0 Chrome/120.0.0.0" },
validateStatus: () => true,
});
const match = response.data.match(
/data-sitekey=["']([0-9x][A-Za-z0-9_-]+)["']/
);
return match ? match[1] : null;
} catch {
return null;
}
}
Часто задаваемые вопросы
Пять вопросов, которые чаще всего задают при настройке автоматизации под оба типа вызова:
- Как отличить Managed Challenge от Interactive Challenge без доступа к панели Cloudflare? Смотрите на HTTP-статус и содержимое ответа: 503 с
challenge-platformили путёмmanagedв скрипте — это Managed Challenge; 403 с видимым виджетом — Interactive Challenge. Функция обнаружения из раздела выше делает это автоматически. - Почему один и тот же сайт то пропускает автоматизацию невидимо, то показывает Turnstile? Managed Challenge пересчитывает риск для каждого запроса: репутация IP и поведенческие сигналы меняются, поэтому один и тот же маршрут может в одном прогоне пройти без проверки, а в другом — потребовать решения через
turnstile. - Нужно ли увеличивать таймаут, если Managed поднимает уровень до JS-задачи? Нет —
cloudflare_challengeрешается в те же сроки, что иturnstile; опрашивайтеres.phpтем же циклом. - Можно ли использовать общий пул потоков CaptchaAI для доменов на Managed и Interactive одновременно? Да, тарификация идёт по потокам, а не по типу CAPTCHA или домену — один план обслуживает оба сценария.
- Как логировать переключения типа вызова для мониторинга? Пишите в лог URL, HTTP-статус и
challenge_typeпри каждом прогоне; рост доли видимых проверок обычно сигнализирует об изменении репутации IP.
Типичные проблемы и что с ними делать
- 503 без видимого виджета — Managed Challenge пройден невидимо, действий не требуется, вы уже прошли.
- 503 с «Проверка браузера» — Managed поднял уровень до JS-задачи, используйте метод
cloudflare_challenge. - 403 с видимой CAPTCHA — Interactive Challenge (наследие), используйте метод
turnstile. - 403 без единого признака проверки — блокировка WAF, а не вызов; смените IP или паттерн запроса.
qa_validation_cookieодного типа не принимается для другого маршрута — на разных маршрутах домена могут действовать разные потоки проверки; решайте тот вызов, который показан именно сейчас.
Пример из практики: staging QA-стенд под Cloudflare
Команда QA-автоматизации тестирует staging checkout за Cloudflare из CI-раннеров в Европе. Днём ~90% прогонов проходят Managed Challenge невидимо, ночью доля видимого Turnstile растёт до 15–20% из-за смены репутации IP-диапазона провайдера. Детектор из раздела выше помечает каждый прогон типом вызова и solve_method, а CaptchaAI решает то, что реально показано, без ручного вмешательства.
Логируя содержимое страниц, собирайте только те данные, на обработку которых у вас есть основание, — для российской юрисдикции это 152-ФЗ «О персональных данных», для трансграничных команд полезно держать в уме и GDPR. Для агентств, проверяющих десятки доменов клиентов, предсказуемая стоимость по потокам CaptchaAI — например, ADVANCE ($90/мес, 50 потоков) — удобнее оплаты за каждое решение.
Краткое содержание
- И Managed Challenge, и Interactive Challenge решаются через CaptchaAI, разница только в деталях.
- Managed Challenge адаптивно подбирает сложность — от невидимого прохождения до полной JS-задачи; решается методом
turnstile(видимый виджет) илиcloudflare_challenge(JS-уровень). - Interactive Challenge всегда показывает видимую CAPTCHA и решается методом
turnstile. - Оба варианта завершаются одним и тем же
qa_validation_cookie, поэтому логика обработки cookie не зависит от типа вызова.