Creuto is now an OpenAI Select Partner Read More

Custom Software Development

Turnstile Spin: letting an agent install bot protection

Turnstile Spin lets your coding agent wire Cloudflare Turnstile into your app. What to check in the diff before you approve the backend Siteverify call.

Turnstile Spin: letting an agent install bot protection

Turnstile Spin hands bot-protection setup to the coding agent you already run. It finds the frontend and backend code, proposes a plan, waits for your approval, and only then edits your repository. Cloudflare reports more than 65,000 successful Spin widget creations since the July release. The part that deserves your review is the backend call.

That is not a throwaway detail. The single most common way a site gets Turnstile wrong is to render the widget, watch the checkbox go green, and never validate the token on the server. Cloudflare now detects exactly that condition and puts a banner on it. Spin is the fix it offers.

What Turnstile Spin actually does to your codebase

Spin is a setup flow, not a hosted service. Cloudflare states plainly that Spin does not send your application code to Cloudflare or ask Cloudflare to change it remotely — the agent you already use makes the approved changes locally. Cloudflare names Claude Code, Cursor and Codex; the mechanism is a skill, so agent choice is largely yours.

You can start it three ways: from the Cloudflare dashboard, from Wrangler, or by pasting a public GitHub skill URL straight into your agent. The third route is the one that matters for teams with an existing agent workflow, because it needs no dashboard visit at all.

Cloudflare describes three scenarios the agent handles: a fresh install that wires the widget and Siteverify from scratch, a recovery pass that adds the missing backend validation to a widget already in production, and a migration that detects a legacy CAPTCHA provider and substitutes Turnstile. Alongside the widget creations, Cloudflare says developers have copied the generated prompt more than 30,000 times, which suggests plenty of teams are running the change by hand rather than letting the agent drive.

Why Turnstile needs backend validation at all

The widget produces a token. The token means nothing until your server posts it to https://challenges.cloudflare.com/turnstile/v0/siteverify with your secret key and reads success back. Until that round trip happens, anyone can submit your form with a fabricated field value, because the client is the one place you cannot trust.

The constraints on that token are specific, and they are where most integrations break. Cloudflare's docs state that a token is valid for five minutes and can only be validated once; a replayed token comes back with the timeout-or-duplicate error code. Tokens run to a maximum of 2,048 characters. Siteverify accepts secret and response, optionally remoteip and an idempotency_key UUID for safe retries, and returns challenge_ts, hostname, action, cdata and an error-codes array.

Cloudflare counts Siteverify calls per widget. Where a widget has none, the dashboard shows a "Fix with Spin" banner — the platform telling you that your bot protection is decorative. That detection is the genuinely new thing here, more than the agent. A misconfiguration that used to surface as a support ticket after an abuse incident now surfaces as a line in a console.

Five things to check before you approve the agent's change

This checklist is ours, not Cloudflare's. An approval gate only works if you know what you are looking for, and "the diff adds a Siteverify call" is not enough. In the systems we build, the failure modes below are what actually bite after a CAPTCHA goes in.

CheckWhy it mattersHow to tell from the diff
Siteverify runs on every submission pathAgents patch the route they find. A second entry point — a mobile client, a public API, a legacy endpoint — stays open.Grep for every handler that writes the same record, not just the one the plan named.
The secret key never reaches the bundleA secret in client code is a secret published.The secret is read from server environment config; the sitekey is the only Turnstile value in frontend files.
A success: false response rejects the requestCode that logs the failure and continues is the same as no validation.The branch returns an error to the caller before any write or send.
timeout-or-duplicate is handled as a real caseTokens expire in five minutes and are single-use, so a slow form or a double-submit produces it in normal traffic.The error path resets the widget and asks for a new token rather than showing a generic 500.
The widget mode matches the formManaged, non-interactive and invisible behave differently for real users.Cloudflare's docs note that invisible mode requires referencing the Turnstile Privacy Addendum in your privacy policy.

None of this is an argument against letting the agent write the change. It is an argument for reading it. The same review discipline applies here as anywhere else agents touch production code — the work moves, but the bottleneck moves to review rather than disappearing.

The reCAPTCHA migration hides a server-side change

Turnstile's compatibility mode makes the frontend swap look trivial. Load the script with ?compat=recaptcha and, per Cloudflare, it registers the API as grecaptcha and provides implicit rendering for reCAPTCHA, so existing grecaptcha.render() calls keep working once you change the sitekey.

The server is where it stops being a drop-in. The verification endpoint moves from Google's to Cloudflare's, and Cloudflare's docs are explicit that Siteverify does not support GET requests with query parameters — it accepts POST only, with a FormData or JSON body. Compatibility currently reaches up to reCAPTCHA v2. If your integration was built against v3 score thresholds, the shim will not carry it.

This is the specific case where Spin earns its keep: the agent reads both halves of your stack, so the backend change does not get forgotten while the frontend looks finished.

What it costs, and when to say no

Turnstile is free. The Free plan allows 20 widgets per account, 10 hostnames per widget and unlimited challenges, with analytics retained for 7 days. Enterprise lifts widgets to unlimited and hostnames to 200, extends analytics to 30 days, and adds ephemeral IDs and removal of Cloudflare branding. For most teams the free tier is the whole story; the 20-widget ceiling is the one that catches multi-brand estates.

Say no to the agent's plan when validation belongs somewhere it did not look. If your submissions already pass through an API gateway or an edge worker, putting the Siteverify call in each application handler duplicates logic you will later have to keep in sync — the same argument that pushes teams toward a production-like URL per branch rather than per-service improvisation. Say no, too, when the form is behind authentication and your real problem is rate limiting, not bots; a CAPTCHA on a logged-in form adds friction and catches nothing.

And check it in a browser before you merge. Agents are now able to drive real browsers for this kind of verification — your coding agent can test your site in Safari 27 — which closes the loop between a plausible diff and a form that actually rejects a forged token.

The decision in front of you is not whether to let an agent write this change. It is whether your approval gate is a read of the diff or a click. For a control whose entire value lives in one server-side call, that difference is the control. If the widget work is part of a broader build, it belongs in the same review process as the rest of your web application development, not in a side quest someone approves between meetings.

Frequently asked questions

Turnstile Spin is a Cloudflare setup flow that lets your own coding agent install Turnstile. The agent locates your frontend and backend code, proposes an integration plan, waits for your approval, then makes the change in your repository. Cloudflare says Spin does not send your application code to Cloudflare.

Cloudflare Turnstile is free. The Free plan allows 20 widgets per account, 10 hostnames per widget, unlimited challenges and seven days of analytics. Enterprise raises widgets to unlimited, hostnames to 200 per widget, analytics to 30 days, and adds ephemeral IDs and removal of Cloudflare branding.

A Turnstile widget only produces a token; the token proves nothing until your server posts it to Cloudflare's Siteverify endpoint with your secret key. Without that call, an attacker can submit your form with any value in the token field, so the widget becomes decoration rather than protection.

Correct Turnstile installation has two halves: render the widget in your frontend with the sitekey, and validate the returned token server-side against Siteverify using the secret key. Reject the request whenever the response reports success as false, and handle expired or replayed tokens explicitly.

Largely yes. Loading Turnstile's script with the compat=recaptcha parameter registers the API as grecaptcha, so existing render calls work after a sitekey swap. The server side still changes: Siteverify accepts POST only, not GET query parameters, and compatibility currently reaches reCAPTCHA v2.

Check that Siteverify runs on every submission path rather than the one route the agent found, that the secret key stays out of the client bundle, that a false success response actually rejects the request, and that expired or duplicate tokens are handled as normal traffic.

Written by

Akash Mohapatra

Akash Mohapatra

Co Founder & Director

26 Sep 2026

·

7 min read

Share

LET'S CONNECT

Connect with Creuto!

Ready to take the first step towards unlocking opportunities, realizing goals, and embracing innovation? We're here and eager to connect.

We don't just aim to fit in – we strive to stand out. Experience the perfect blend of innovation, excellence, and trust that makes us truly unforgettable. Discover the difference with Creuto.

© 2026 Creuto All Rights Reserved