Skip to content

Cloudflare WAF managed challenge test page

This page sits behind a Cloudflare WAF custom rule whose action is Managed Challenge: before it loads, Cloudflare shows its "Just a moment..." page and decides whether the visitor must interact. Reaching this text means you passed, and the check below says whether your browser holds a clearance.

Your pass

Live

Checking your clearance…

Asking whether your browser sent cf_clearance with this page.

WAF rule action
managed_challenge (Managed Challenge)
Rule
Live on this site
Clearance level
Managed: passes Managed and JS challenges
cf_clearance sent
checking…
Through Cloudflare
checking…
Clearance lasts
The site's Challenge Passage, 30 minutes by default

Checking whether your browser holds a cf_clearance cookie for this site…

Test it again

A private window holds no clearance, so Cloudflare challenges it again: copy this page's link and open it there. Or point a task at the page, below.

Test with the API

What a task returns

A CloudflareChallengeTask opens this page through your proxy in a real browser and passes the challenge. Once it is ready, getTaskResult holds what that browser earned.

solution.cookies.cf_clearance
The clearance. Send it as the cf_clearance cookie with every request to the site.
solution.userAgent
The browser it was issued to. Send it as the User-Agent header, unchanged.
expiresAt
When the API stops serving it: 30 minutes after the solve. The site's Challenge Passage decides how long Cloudflare accepts it.

getTaskResult, once it is ready

{
  "errorId": 0,
  "taskId": "0192f3a4-7b1c-7d2e-9f10-3c4d5e6f7a8b",
  "status": "ready",
  "solution": {
    "type": "cloudflare",
    "token": "Dyw1BhDnEAGRy5fh…",
    "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/151.0.0.0 Safari/537.36",
    "cookies": { "cf_clearance": "Dyw1BhDnEAGRy5fh…" }
  },
  "expiresAt": "2026-09-30T14:32:14Z"
}

Send the cookie and the user agent with every request, through the same proxy: Cloudflare ties the clearance to the visitor and device it was issued to. When the site challenges you again, create a new task.

Solve this page with the API

The complete createTask request for this page, then getTaskResult every 2 seconds until it is ready, then the result used as the page uses it. Set ZEROCAPTCHA_KEY to your API key, and PROXY_URL to your proxy.

type
CloudflareChallengeTask
websiteURL
https://zerocaptcha.io/captcha-test/cloudflare-managed-challenge
proxy
Required: the clearance works only from its address
callbackUrl
Optional: called with the result when the task ends
Idempotency-Key
A header: sent again within 24 hours, it returns the first task

A task is charged at the listed price when it succeeds; a failed one costs nothing. The same task over REST, POST /v1/tasks, is inCloudflare WAF and 5-second challenges.

#!/usr/bin/env bash
# Pass this page's Cloudflare challenge through your proxy with createTask, then load the page
# with the clearance.
set -euo pipefail
API=${ZEROCAPTCHA_API:-https://api.zerocaptcha.io}
KEY=${ZEROCAPTCHA_KEY:?Set ZEROCAPTCHA_KEY to your API key, zc_live_..., from the dashboard.}
PROXY=${PROXY_URL:?Set PROXY_URL to your proxy, such as http://user:pass@proxy.example.net:8080}
PAGE=https://zerocaptcha.io/captcha-test/cloudflare-managed-challenge

# 1. createTask for this page, through the proxy you will browse with: the clearance only works
#    from its address. CALLBACK_URL, when set, is called with the result when the task ends.
BODY=$(jq -n --arg key "$KEY" --arg proxy "$PROXY" --arg callback "${CALLBACK_URL:-}" '{
  clientKey: $key,
  task: {
    type: "CloudflareChallengeTask",
    websiteURL: "https://zerocaptcha.io/captcha-test/cloudflare-managed-challenge",
    proxy: $proxy
  },
  callbackUrl: (if $callback == "" then null else $callback end)
}')
CREATED=$(curl -sS --fail-with-body "$API/createTask" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d "$BODY")
# errorId 1 is a refusal: errorCode and errorDescription say why.
if [ "$(jq -r .errorId <<<"$CREATED")" != 0 ]; then echo "$CREATED" >&2; exit 1; fi
TASK_ID=$(jq -r .taskId <<<"$CREATED")

# 2. getTaskResult every 2 seconds until the task is ready; errorId 1 means it failed, unpaid.
while :; do
  sleep 2
  RESULT=$(curl -sS --fail-with-body "$API/getTaskResult" \
    -H "Content-Type: application/json" \
    -d "$(jq -n --arg key "$KEY" --arg id "$TASK_ID" '{clientKey: $key, taskId: $id}')")
  if [ "$(jq -r .errorId <<<"$RESULT")" != 0 ]; then echo "$RESULT" >&2; exit 1; fi
  if [ "$(jq -r .status <<<"$RESULT")" = ready ]; then break; fi
done
CLEARANCE=$(jq -r .solution.cookies.cf_clearance <<<"$RESULT")
USER_AGENT=$(jq -r .solution.userAgent <<<"$RESULT")

# 3. Come back as the browser that passed: the same proxy, user agent and cookie. A client whose
#    TLS does not look like that browser may be challenged again (use curl-impersonate).
curl -sS -o /dev/null -w "page: HTTP %{http_code}\n" \
  -x "$PROXY" -A "$USER_AGENT" -b "cf_clearance=$CLEARANCE" "$PAGE"
curl -sS -x "$PROXY" -A "$USER_AGENT" -b "cf_clearance=$CLEARANCE" \
  "https://zerocaptcha.io/api/v1/demo/clearance"

What this challenge is

A Managed Challenge lets Cloudflare choose the challenge for each request: most people pass without doing anything, some are asked for a click. Cloudflare recommends it for most WAF rules. Passing earns a cf_clearance cookie at the managed level, which also covers Non-Interactive (JS) challenges.

It is an interstitial page in front of the site, not a widget in it: there is no sitekey and no token, only the cookie.

How to use the result

The task's result is the cf_clearance cookie and the user agent it was issued to. Send both with every request to the site, through the same proxy the task used: Cloudflare ties the cookie to "the specific visitor and device it was issued to", which in practice means that address and that user agent.

The clearance lasts for the zone's Challenge Passage time, 30 minutes by default, and covers challenge rules at its level or below. A client whose TLS handshake does not look like the browser its user agent names may be challenged again, so use a browser or a client that impersonates one.

How to recognise it on a real site

  • The first response has the header cf-mitigated: challenge and the content type text/html, whatever was asked for; in our checks the status was 403 and the page title "Just a moment...".

  • The challenge page loads its scripts from the site's own /cdn-cgi/challenge-platform/ path, then posts its result there and reloads the page.

  • Passing sets the cf_clearance cookie on the site, with SameSite=None, Secure and Partitioned.

What a challenge page looks like (its markup is not documented and changes)
<!-- The first response: HTTP 403, cf-mitigated: challenge, text/html -->
<title>Just a moment...</title>
<script>window._cf_chl_opt = { /* the challenge's settings */ };</script>
<script src="/cdn-cgi/challenge-platform/h/b/orchestrate/chl_page/v1?ray=…"></script>
<!-- Passing sets: cf_clearance=…; SameSite=None; Secure; Partitioned -->

Managed challenge questions

Which ZeroCaptcha task passes the Cloudflare WAF managed challenge?

CloudflareChallengeTask, with the page's URL and your proxy. It returns the cf_clearance cookie and the user agent it was issued to; there is no proxyless challenge task, because the cookie only works from the address that earned it.

Does a managed clearance pass the other challenges?

It passes Managed and Non-Interactive challenges. An Interactive Challenge needs an interactive clearance.

Does solving a demo page cost anything?

A task pointed at a demo page is an ordinary task: it is charged at the price list's rate when it succeeds, and a failed or expired task costs nothing. Opening the page and checking its token are not charged.