One genuine Cloudflare Turnstile widget — the invisible challenge — on a sitekey we own, declared in this page's markup and nowhere else. There is nothing on screen to click: the challenge runs in the background and drops its token into a hidden input. Solve it yourself, or point a solve call at this URL and paste the token back. Either way the verdict is Cloudflare's, checked server-side against siteverify with our secret key.
// this page carries one widget only · the managed one lives at /demo/managed · both, explained
One live Turnstile widget, rendered from the markup in this page — not injected by our JavaScript.
One sitekey per document: a token issued here means nothing to the managed widget, and the reverse. Verifying against the wrong secret reads as a bad token.
Open the managed challenge →Your token goes to siteverify with that widget's secret key. What comes back is printed here unedited.
Nothing verified yet. Hand us a token and hit verify — the answer below comes from Cloudflare, not from us.
View source and you'll find exactly this — one element, one sitekey. Turnstile's implicit rendering mode reads the attribute off it; the challenge is in the document, not assembled at runtime, which is why a crawler or a headless client sees the same gate you do.
<div class="cf-turnstile"
data-sitekey="0x4AAAAAAER49t0sMxTcief0"></div>
<script defer
src="https://challenges.cloudflare.com/turnstile/v0/api.js"></script>This page is a stable test target: the sitekey and URL don't move. Send them to /v1/solve, take the token from the response, and paste it into the box above to watch Cloudflare accept it. Full reference in the docs.
curl https://solvegate.io/v1/solve \
-H "Authorization: Bearer sk_live_…" \
-H "content-type: application/json" \
-d '{
"gate": "turnstile",
"url": "https://solvegate.io/demo/invisible",
"sitekey": "0x4AAAAAAER49t0sMxTcief0"
}'First 1,000 solves are free. No card, no call — a key and one POST.
// this demo verifies tokens against our own sitekeys only — see acceptable use