Skip to content

Cloudflare Turnstile login form demo

This page is a sign-in form protected by a Cloudflare Turnstile widget with the action login, built the way real sites build them. Nothing you type is sent or kept: only the widget's token goes to the check, which asks Cloudflare's siteverify for its verdict.

The sign-in form

Live

For show: nothing you type in these two fields is sent or kept.

Check a token from a task

A task's solution.token for this page. It passes once, within 300 seconds of the solve.

This widget's settings

Sitekey0x4AAAAAAFMVDQUY9ZAPO0ni
Mode
managed
Appearance
always
Size
normal
Rendering
implicit
Action
login
Task
TurnstileTaskProxyless

The verdict

The token goes to this site's API, which asks Cloudflare's siteverify with the widget's secret key. The reply is shown as it came.

No token checked yet

Sign in once the widget has a token, or paste a token a task returned for this page.

success
not checked yet
hostname
not checked yet
challenge_ts
not checked yet
action
not checked yet
cdata
not checked yet
error-codes
not checked yet
Widget
not checked yet
Round trip
not checked yet

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.

type
TurnstileTaskProxyless, or TurnstileTask with your proxy
websiteURL
https://zerocaptcha.io/captcha-test/cloudflare-turnstile-login-form
websiteKey
0x4AAAAAAFMVDQUY9ZAPO0ni
metadata.action
login
metadata.cdata
This widget sets none
proxy
Only with TurnstileTask: http://user:pass@host:port
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 inSolving Cloudflare Turnstile.

#!/usr/bin/env bash
# Solve this page's Cloudflare Turnstile widget with createTask, then check the token here.
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.}

# 1. createTask for this page and its sitekey.
#    metadata holds this widget's data-action and data-cdata: a site that checks them
#    refuses a token solved without them, so copy them from the widget you solve.
#    To solve through your own proxy, make the type TurnstileTask and add
#    proxy: "http://user:pass@proxy.example.net:8080" to the task.
#    CALLBACK_URL, when set, is called with the result when the task ends.
BODY=$(jq -n --arg key "$KEY" --arg callback "${CALLBACK_URL:-}" '{
  clientKey: $key,
  task: {
    type: "TurnstileTaskProxyless",
    websiteURL: "https://zerocaptcha.io/captcha-test/cloudflare-turnstile-login-form",
    websiteKey: "0x4AAAAAAFMVDQUY9ZAPO0ni",
    metadata: {action: "login"}
  },
  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
TOKEN=$(jq -r .solution.token <<<"$RESULT")

# 3. Use solution.token once, within 300 seconds: here, this page's check, which asks
#    Cloudflare's siteverify. Or paste it into the token box on the page.
curl -sS --fail-with-body "$API/v1/demo/verify" \
  -H "Content-Type: application/json" \
  -d "$(jq -n --arg token "$TOKEN" '{widget: "managed", token: $token}')"

What this widget is

Login forms are among the most common places to meet Cloudflare Turnstile. The widget sits between the password field and the button, and the form sends its token with the email and password. The site's server checks the token with siteverify before it looks at the password.

Automating a sign-in you are allowed to automate is two steps: get a token for the form, then send the form with it, as the browser would.

Bring a token from elsewhere: the Cloudflare Turnstile token checker.

How to use the result

Send the token in the form's request, in the cf-turnstile-response field, with the email and password. On this page the form sends only the token, to the check beside it.

A token passes siteverify once, within 300 seconds of the solve. Solve again for each sign-in attempt.

How to recognise it on a real site

  • A cf-turnstile element inside the sign-in form, usually with data-action="login", and a cf-turnstile-response field in the form's request when it is sent.

  • The page loads https://challenges.cloudflare.com/turnstile/v0/api.js, the only script Cloudflare supports: it must not be copied, proxied or cached.

  • The widget itself is an iframe from challenges.cloudflare.com, under /cdn-cgi/challenge-platform/. Its requests go to Cloudflare, never to the site.

  • Inside a form, the widget adds a hidden input named cf-turnstile-response and puts the token there. The site's server checks it with POST https://challenges.cloudflare.com/turnstile/v0/siteverify.

  • No cookie is set on the site's own domain: the widget's state lives in Cloudflare's iframe.

This page's widget markup
<script src="https://challenges.cloudflare.com/turnstile/v0/api.js" async defer></script>
<div class="cf-turnstile" data-sitekey="0x4AAAAAAFMVDQUY9ZAPO0ni" data-action="login"></div>
<!-- once solved: <input type="hidden" name="cf-turnstile-response" value="…"> -->

Login form questions

Which ZeroCaptcha task solves the Cloudflare Turnstile widget on a login form?

TurnstileTaskProxyless, or TurnstileTask to solve through your own proxy, with the page's URL and its sitekey, plus action and cdata when the widget sets them. The same task solves every Cloudflare Turnstile widget, whatever its mode or appearance.

Is my password sent anywhere by this demo?

No. The email and password fields are for show: the page sends only the widget's token to the check, and nothing is kept.