Turnstile
Turnstile is a Cloudflare challenge widget that issues a token when a visitor's browser passes a set of non-interactive checks, which the site's backend then validates through the siteverify API. This page documents the widget modes, the token lifecycle, documented limits and integration requirements.
Document control
Document control. Vendor: Cloudflare, Inc. Document owner: Dana, technical writer, Integrity Czech Republic s.r.o. Last reviewed: 2026-08-31. Content snapshot of the referenced Cloudflare documentation: 2026-08-28. Figures in this document were verified against the sources listed under References on the dates shown there; Cloudflare changes limits and packaging without notice, so verify at the source before you design against a value.
Overview
Turnstile is a challenge mechanism for web forms and endpoints. It replaces an interactive puzzle with a set of checks executed in the visitor's browser. On success it produces a token, which the site submits to Cloudflare's siteverify endpoint from its own backend to confirm that the challenge was passed for that site.
Turnstile can be used on any website. The site does not need to be proxied through Cloudflare, and no Cloudflare zone plan is required.
Cloudflare states that Turnstile presents no images or text to decipher (https://developers.cloudflare.com/turnstile/, retrieved 2026-08-28). In managed mode, a visitor may be asked for a single interaction such as a checkbox. The solve rate for a given deployment is visible in the widget analytics.
Where the effect on conversion matters, measure completion rate on your own forms before and after deployment.
Architecture
A Turnstile deployment has three parts:
- The widget. A small JavaScript component embedded on the page, configured with a public sitekey. It executes challenges in the browser: JavaScript proofs of work, browser environment consistency checks and behavioural signals. It does not require the site to be behind Cloudflare.
- The token. On success the widget writes a token into the form, or returns it through a callback. The token is a claim that the challenge was passed for a specific sitekey.
- Server-side validation. The backend posts the token, together with the secret key, to
https://challenges.cloudflare.com/turnstile/v0/siteverify. The response indicates success or failure with error codes, and includes the hostname and challenge timestamp. Only after a successful validation should the backend accept the submitted action.
The server-side step is what provides the security property. A token present in a request that is never validated proves nothing, because the request body is under the client's control. Cloudflare documents the token as valid for 300 seconds and as validatable once; a second validation of the same token fails (https://developers.cloudflare.com/turnstile/get-started/server-side-validation/, retrieved 2026-08-28). An idempotency_key may be supplied where the same token must be validated again as part of a retry.
On zones proxied through Cloudflare, Turnstile can additionally issue pre-clearance, so that a visitor who has passed the widget is not challenged again by WAF or Bot Management rules for the duration of the clearance.
Capabilities
| Capability | Behaviour | Availability | Source |
|---|---|---|---|
| Managed mode | Cloudflare decides whether an interaction is required. Most sessions complete without one; some are asked for a single interaction such as a checkbox. | All accounts. | Widget types |
| Non-interactive mode | A visible widget that never requests an interaction. | All accounts. | Widget types |
| Invisible mode | No visible widget; the challenge runs without a rendered element. | All accounts. | Widget types |
| Implicit and explicit rendering | Automatic rendering from a container element, or programmatic rendering through turnstile.render() for dynamic forms and single-page applications. | All accounts. | Client-side rendering |
| Server-side validation | siteverify endpoint returning success, error codes, hostname, action, cdata and challenge timestamp. | All accounts. | Server-side validation |
| Hostname and action binding | A widget is bound to configured hostnames; an action and cdata value can be set client side and checked in the validation response. | All accounts. | Widget configuration |
| Pre-clearance | Issues a clearance cookie so that WAF and Bot Management rules do not re-challenge the session on a proxied zone. | Requires the protected site to be proxied through Cloudflare. | Pre-clearance |
| Ephemeral IDs | Returns a rotating identifier in the validation response that can be used to correlate repeated attempts from the same client without storing personal data. | All accounts. | Ephemeral IDs |
| Analytics | Solve rates, challenge volume and widget performance per sitekey. | All accounts. | Turnstile analytics |
Configuration model
The configuration object is the widget, identified by a sitekey and paired with a secret key. Widget settings are:
- Mode. Managed, non-interactive or invisible.
- Hostnames. The domains on which the widget is permitted to render. The hostname is returned in the validation response and should be checked by the backend.
- Domain enforcement. Whether hostname validation is applied strictly.
- Pre-clearance. Whether the widget issues clearance, and its scope.
- Appearance and execution. Whether the widget renders always or only when interaction is needed, and whether the challenge executes on render or on demand.
Client-side parameters set per instance include action, a label distinguishing which form produced the token, and cdata, an opaque value returned in the validation response. Both are returned by siteverify and should be checked, because they bind a token to the specific operation it was issued for.
Cloudflare publishes test sitekeys and secret keys that always pass, always fail or always require interaction. Use them in automated tests rather than disabling validation in test environments, because a disabled validation path frequently reaches production.
The secret key must be held server side only. A deployment that renders the widget but never calls siteverify, or that calls it from client-side code, provides no protection. This is a common Turnstile integration defect.
Limits and constraints
Documented limits, verified 2026-08-31 against https://developers.cloudflare.com/turnstile/plans/:
| Limit | Standard | Enterprise |
|---|---|---|
| Widgets per account | 20 | Unlimited |
| Hostnames per widget | 10 | 200 |
| Analytics lookback | 7 days | 30 days |
Token behaviour, from https://developers.cloudflare.com/turnstile/get-started/server-side-validation/, retrieved 2026-08-28: a token is valid for 300 seconds, and a token can be validated once unless an idempotency_key is supplied.
Further constraints:
- Cloudflare does not publish a monthly quota for siteverify requests, so do not design against a monthly figure quoted elsewhere.
- Widget and hostname allowances above the standard values require an Enterprise arrangement. The hostname allowance of 10 per widget is the constraint most deployments reach first, because domains accumulate over time.
- Turnstile protects the specific endpoints where the widget is rendered and where the token is validated. Endpoints without a widget, including mobile APIs and legacy paths, are unaffected.
- The widget requires JavaScript in the browser. Clients that do not execute JavaScript cannot obtain a token, so an endpoint that must serve such clients needs an alternative control.
- Non-browser clients, including server-to-server API consumers, cannot complete the challenge. Do not place Turnstile in front of a machine-to-machine endpoint.
- Pre-clearance applies only where the protected site is proxied through Cloudflare.
- Turnstile returns a decision about a browser session. It does not authenticate a user and does not establish that the submitted content is legitimate.
- Privacy and regulatory compliance for a specific deployment depend on how the site processes the data around the widget and on the applicable legal assessment. Use Cloudflare's own statements about the data Turnstile collects as input to that assessment.
Plan availability
| Tier | Included |
|---|---|
| Standard | Available at no cost, including for commercial sites, within the documented limits: 20 widgets per account, 10 hostnames per widget and 7 days of analytics lookback. No Cloudflare zone plan is required. |
| Enterprise | Unlimited widgets, up to 200 hostnames per widget, 30 days of analytics lookback, and additional features and support under a contract. |
| Pre-clearance | Requires the protected site to be proxied through Cloudflare on any zone plan. |
Accurate as of 2026-08-31 against https://developers.cloudflare.com/turnstile/plans/. Limits and packaging change without notice. Confirm at the source before designing against these values.
Deployment
Prerequisites.
- Identify the endpoints experiencing abuse and the evidence for it: fake registrations, credential stuffing attempts, comment or contact form spam, or coupon and voucher abuse.
- Identify every service that accepts the affected submissions. A single form frequently posts to more than one backend, and each one that accepts the action needs validation.
- Record which of those endpoints are also called by non-browser clients, since those cannot complete a challenge.
- Record baseline metrics: submission volume, completion rate and the abuse metric identified above.
- Identify any existing CAPTCHA integration to be replaced, and the code paths that reference it.
- Confirm where the secret key will be stored, and that it is not present in any client-side bundle or repository.
Staged validation. Deploy on one endpoint with a clear abuse signal. Implement the widget and the server-side validation together, and log validation outcomes without rejecting submissions for an initial period. Review the proportion of submissions arriving with a valid token, an invalid token or no token at all. Use Cloudflare's test keys to confirm that the failure path rejects correctly before enforcing.
Configuration.
- Create a widget per logical application rather than one per form, and configure its hostnames.
- Set an
actionvalue per form so that tokens are attributable, and check it in the validation response. - Implement server-side validation in every service that accepts a protected submission. Treat a missing or invalid token as a rejection.
- Check the
hostnameandactionfields in the siteverify response, not only thesuccessfield. - Choose the widget mode per form: invisible or non-interactive where the abuse level permits, managed where it does not.
- Handle the token expiry and error callbacks in the client so that a visitor on a slow form is re-issued a token rather than receiving an unexplained failure.
- Where the site is proxied through Cloudflare, enable pre-clearance and pair Turnstile with rate limiting rules and, where licensed, bot rules.
- Remove the previous CAPTCHA integration and its keys only after the new path is verified.
Cutover. Enable rejection of unvalidated submissions on one endpoint at a time, monitoring completion rate at each step. Keep the previous control in place until the endpoint is verified, then remove it.
Verification.
- Confirm that a submission with no token is rejected by the backend, tested directly against the endpoint rather than through the form.
- Confirm that a replayed token is rejected on second use.
- Confirm that the secret key does not appear in any client-side asset.
- Confirm that completion rate on the protected forms has not moved outside its normal range.
- Confirm that the abuse metric recorded during prerequisites has changed in the expected direction, and check whether the activity has moved to an adjacent endpoint.
- Confirm behaviour on the browsers and assistive technologies in your supported matrix.
Rollback. Disable enforcement in the backend, which restores the previous acceptance behaviour without a frontend release, and leave the widget rendering while the cause is investigated. Retain the previous control's code path until the deployment is confirmed stable.
Operational considerations
Monitor solve rates and validation failure rates per widget. A rise in validation failures usually indicates a client-side error, an expired token on a long form, or a change in the form's submission flow rather than an increase in attacks.
Watch for displacement after deployment. When a protected form becomes expensive, activity commonly moves to an unprotected endpoint such as a mobile API or an older path. Include those endpoints in the review.
Rotate the secret key on a defined schedule and after any incident involving the backend, and store it with the rest of your secrets rather than in configuration files.
Keep the token expiry in mind when designing multi-step forms. A token issued at the start of a long flow may be past its 300 second validity by the time the form is submitted; re-execute the challenge before submission in that case.
Track the number of hostnames configured on each widget against the documented allowance, because adding a domain to a widget that has reached the limit fails at configuration time rather than at runtime.
Failure modes to plan for: a frontend release that removes the token field, a backend release that stops calling siteverify, a content security policy change that blocks the widget script, and a widget hostname list that does not include a newly added domain or that has reached the documented maximum.
Known caveats
- A widget without server-side validation provides no protection. This is a common integration defect, and it is not visible from the user interface, because the form still displays and still submits.
- Checking only the
successfield ignores the hostname and action binding, which allows a token obtained on one form or one site to be replayed on another within its validity window. - Tokens are valid for 300 seconds and are single use unless an idempotency key is supplied. Long forms and retry logic must account for both.
- Managed mode may present a single interaction such as a checkbox. It does not present image or text puzzles.
- Clients that do not execute JavaScript cannot obtain a token, which affects accessibility tooling, some embedded browsers and legitimate automation.
- Turnstile protects the endpoints where it is deployed. It is one layer, and endpoints without a widget remain unprotected.
- Pre-clearance requires the site to be proxied through Cloudflare and does not apply to sites hosted elsewhere.
- Widget and hostname allowances are finite: 20 widgets per account and 10 hostnames per widget on the standard tier. A deployment that adds domains over time reaches the hostname limit before it reaches any other documented constraint.
Interoperability
On a proxied zone, Turnstile pre-clearance is honoured by WAF custom rules and Bot Management rules, so a visitor verified once is not challenged again for the clearance duration.
Turnstile composes with rate limiting rules, which bound the volume of attempts against an endpoint regardless of challenge outcome, and with bot rules, which act on classification. The three address different properties and are commonly deployed together.
The siteverify call is an ordinary HTTPS request and can be made from any backend, including a Cloudflare Worker acting in front of an origin, which allows validation to happen at the edge rather than in the application.
Ephemeral IDs returned by siteverify can be correlated with application-side abuse signals without storing an address or a persistent identifier.
Turnstile is independent of DNS and zone configuration, so it can be deployed on sites hosted anywhere and later paired with Cloudflare proxying if the site moves.
FAQ
Is the server-side call required? Yes. Without a siteverify call the token is unverified data supplied by the client, and the widget provides no protection.
How long is a token valid, and can it be validated twice? Cloudflare documents a validity of 300 seconds and a single validation per token. Supply an idempotency_key where a retry must validate the same token again.
Does the site need to be on Cloudflare? No. The widget and siteverify work for any site. Pre-clearance is the one capability that requires the site to be proxied through Cloudflare.
What replaces a reCAPTCHA integration? The client-side widget follows implicit and explicit rendering patterns, and the server-side change substitutes the verification endpoint and secret. Both sides must be changed together, and the previous keys should be removed only after the new path is verified.
References
- https://developers.cloudflare.com/turnstile/, retrieved 2026-08-28.
- https://developers.cloudflare.com/turnstile/plans/, retrieved 2026-08-31.
- https://developers.cloudflare.com/turnstile/concepts/widget/, retrieved 2026-08-28.
- https://developers.cloudflare.com/turnstile/get-started/client-side-rendering/, retrieved 2026-08-28.
- https://developers.cloudflare.com/turnstile/get-started/server-side-validation/, retrieved 2026-08-28.
- https://developers.cloudflare.com/turnstile/concepts/pre-clearance-support/, retrieved 2026-08-28.
- https://developers.cloudflare.com/turnstile/concepts/ephemeral-id/, retrieved 2026-08-28.
- https://developers.cloudflare.com/turnstile/troubleshooting/testing/, retrieved 2026-08-28.
Content snapshot: 2026-08-28. Limits re-verified 2026-08-31.
Changelog
| Date | Change | Author |
|---|---|---|
| 2026-08-31 | Rewritten as a technical reference. Added limits and plan availability tables with sources. | Integrity documentation team |
| 2026-08-28 | Initial publication. | Integrity documentation team |
Contents
51 pages mirrored from the Cloudflare documentation for turnstile.
Pages
- Additional configurations
- Community resources
- Concepts
- Extensions
- Get started
- Migration
- Cloudflare Turnstile
- Plans
- Reference
- Turnstile Spin
- Troubleshooting
- Turnstile Analytics
- Tutorials
Additional configurations
- Ephemeral IDs
- Hostname management
- Any Hostname (Enterprise only)
- Pre-clearance configuration
- Remove Cloudflare branding with Offlabel
- Pre-clearance support
Concepts
Extensions
Get started
- Embed the widget
- Widget configurations
- Mobile implementation
- Validate the token
- Widget management
- Create and manage widgets using Cloudflare API
- Create and manage widgets using the Cloudflare dashboard
- Create and manage widgets using Terraform
Migration
Reference
Troubleshooting
- Challenge solve issues
- Client-side errors
- Error codes
- Feedback reports
- Rotate secret key
- Test your Turnstile implementation
