> ## Documentation Index
> Fetch the complete documentation index at: https://docs.raykoi.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Cloudflare Turnstile

> Get a site key and secret key from Cloudflare, then connect it to Raykoi.

<Info>
  CAPTCHA — bring-your-own-keys or [Managed](/essentials/pro-features/managed-captcha) — requires the **Starter plan or above**. Toggling it on below a Starter plan returns a `403`.
</Info>

<Steps>
  <Step title="Open the Turnstile dashboard">
    Sign in at [dash.cloudflare.com](https://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.
  </Step>

  <Step title="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.
  </Step>

  <Step title="Choose a widget mode">
    <ParamField body="Managed" type="mode">
      Cloudflare decides whether to show a visible checkbox based on risk signals. The default, and what most forms should use.
    </ParamField>

    <ParamField body="Non-Interactive" type="mode">
      Always invisible, no checkbox ever — a lighter-weight check than Managed.
    </ParamField>

    <ParamField body="Invisible" type="mode">
      Fully invisible, zero UI. Corresponds to Raykoi's `widgetMode: 'invisible'`.
    </ParamField>

    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.
  </Step>

  <Step title="Copy your keys">
    After creation, Cloudflare shows a **Site Key** and a **Secret Key**.

    <Warning>
      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).
    </Warning>
  </Step>

  <Step title="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](/api-reference/get-form-schema)'s `captcha` field — you never hardcode either value into your integration.
  </Step>
</Steps>

## 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.
