All three work the same way: a script scores the visitor, usually without a puzzle, and writes a token into your form, such as Turnstile 2 's <div class="cf-turnstile" data-sitekey="...">. Your server must post that token with its secret key to the vendor's siteverify endpoint; a token checked only in the browser protects nothing.
| Service | Free tier | Paid tiers |
|---|---|---|
| reCAPTCHA 1 (Google Cloud 1 ) | 10,000 assessments/month | $8 up to 100,000; then $1 per 1,000 |
| hCaptcha | Basic plan | Pro from $99/month |
| Cloudflare Turnstile | Unlimited, 20 widgets | Enterprise (quote) |
const body = new URLSearchParams({ secret: process.env.TURNSTILE_SECRET,
response: req.body['cf-turnstile-response'] }); // field the widget adds
const url = 'https://challenges.cloudflare.com/turnstile/v0/siteverify';
const result = await (await fetch(url, { method: 'POST', body })).json();
if (!result.success) return res.status(403).json(result['error-codes']);Turnstile tokens expire after five minutes and validate once, and it runs on any site, proxied by Cloudflare 2 or not. hCaptcha mirrors reCAPTCHA's API, so switching is mostly a change of script URL and keys.