Skip to main content
CAPTCHA — bring-your-own-keys or Managed — requires the Starter plan or above. Toggling it on below a Starter plan returns a 403.
1

Open the Turnstile dashboard

Sign in at dash.cloudflare.com, then go to Turnstile in the left sidebar (or navigate directly to dash.cloudflare.com/?to=/:account/turnstile). A free Cloudflare account is enough — you don’t need your domain’s DNS on Cloudflare to use Turnstile.
2

Add a site

Click Add site. Give it a name (for your own reference — visitors never see it) and enter the domain(s) it’ll run on.
3

Choose a widget mode

mode
Cloudflare decides whether to show a visible checkbox based on risk signals. The default, and what most forms should use.
mode
Always invisible, no checkbox ever — a lighter-weight check than Managed.
mode
Fully invisible, zero UI. Corresponds to Raykoi’s widgetMode: 'invisible'.
Raykoi’s SDK auto-acquires a token without rendering anything for invisible/non-interactive modes. If Cloudflare shows a visible challenge (Managed mode under elevated risk), the SDK surfaces that — solve it the way you would any visible Turnstile widget.
4

Copy your keys

After creation, Cloudflare shows a Site Key and a Secret Key.
The Secret Key authenticates server-side verification calls — never put it in client-side code. Only the Site Key belongs in your frontend (and Raykoi doesn’t even need that from you directly — see below).
5

Connect it to Raykoi

In your form’s Spam Protection settings, choose Cloudflare Turnstile, and paste in both keys. Raykoi stores the secret server-side and resolves the site key to your frontend automatically via Get a Form’s Schema’s captcha field — you never hardcode either value into your integration.

Verifying it’s working

Submit a test entry through your actual integration. If the token never reaches Raykoi (check the Activity tab or your browser’s network inspector for a captcha_token in the request body), the most common cause is the widget script being blocked — an ad blocker, a strict Content Security Policy, or a domain mismatch between what you entered in step 2 and where the form is actually embedded.