← guides
free tool · no account

Cloudflare Turnstile checker: is it there, and what is the sitekey?

Paste a URL. We fetch it once and report what the served HTML actually says about Turnstile — whether the widget is there, its sitekey, how it is rendered, its configuration, whether the key is one of Cloudflare's test keys, and whether you are looking at a WAF challenge page instead of a widget.

// free · no account · we fetch the page once from our own address and read the HTML it returns

What the checker reports

It reads the HTML the server returns — the same bytes a crawler, a CI job or any non-browser client receives. Everything below is either in that response or it is not, and nothing is inferred beyond it.

  • Whether Turnstile is present at all — a script tag for challenges.cloudflare.com/turnstile/v0/api.js, a container with class="cf-turnstile", or a turnstile.render() call.
  • The sitekey, from data-sitekey or from the sitekey option passed to turnstile.render(). Sitekeys are public by design — they are in the page for every visitor to read.
  • Implicit or explicit rendering. Implicit means api.js finds the container in the document; explicit means the page calls turnstile.render() itself, which is what single-page apps do.
  • The widget's configurationdata-action, data-cdata, data-size, data-theme, data-appearance, and the response field name if it has been renamed from cf-turnstile-response.
  • Whether the key is a Cloudflare test key, which means you are looking at a staging build rather than production.
  • Whether it is a WAF challenge instead — a different product, with no sitekey and a different fix.

What it cannot tell you, and why

The widget mode. Managed, non-interactive and invisible are set per widget in the Cloudflare dashboard and stored against the sitekey inside the account that owns it. The page carries the key and nothing else, so the mode is genuinely not in the source — not for us, and not for any other checker that claims otherwise. What you can do is observe: a container that renders at zero height and never appears is invisible, and a checkbox that appears at any point means managed, because interaction is a managed-mode state. The widget modes page works through the ambiguous case.

A widget that only exists after JavaScript runs. We read the served HTML, not a rendered page. If a site injects its widget from a bundle after load, the checker reports no sitekey and says so plainly rather than guessing. That gap is worth knowing about: it is also what a crawler and a scripted client see.

Whether the key is valid, or which hostnames it allows. That lives in the Cloudflare account, and nothing outside it can read it. A sitekey rejected on your domain usually means the hostname is not on the widget's allowed list, which surfaces as invalid-input-response on validation.

Cloudflare's test sitekeys

If the key on a page is one of these, the widget is wired for automated tests and will behave the same way every time. These are the only sitekeys whose widget type is public — Cloudflare documents it, so the checker reports it.

SitekeyBehaviourWidget type
1x00000000000000000000AAAlways passesVisible
2x00000000000000000000ABAlways failsVisible
1x00000000000000000000BBAlways passesInvisible
2x00000000000000000000BBAlways failsInvisible
3x00000000000000000000FFForces an interactive challengeVisible

There are matching secret keys for server-side validation, and the full set is on the Turnstile test keys page.

Doing this yourself

Nothing here is privileged. curl the page and grep for data-sitekey and you have most of it; the sitekey guide covers the explicit-rendering case, extracting a key with Playwright, and the keys you will find that are not real. This page exists because doing it repeatedly is tedious, not because it is hard.

Once you have the sitekey and the page URL, that pair is the whole input to a solve — the mode makes no difference to the request. The solve reference has the call, and the Turnstile solver covers what happens next.

Limits and fair use

One fetch per check, capped at 2 MB and ten seconds, twenty checks per ten minutes per address. We only ever issue a plain GET, we identify ourselves in the User-Agent, and we return extracted fields rather than the page — this is a checker, not a proxy. Private and reserved addresses are refused, so it cannot be pointed at anything inside a network it can reach but you cannot.

Found the gate? Clear it.

// sitekey + url in, token back in under 1.5s · first 1,000 solves free