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

# hCaptcha

> Get a site key and secret key from hCaptcha, 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="Create an hCaptcha account">
    Sign up at [dashboard.hcaptcha.com/signup](https://dashboard.hcaptcha.com/signup) (or sign in if you already have one).
  </Step>

  <Step title="Add a new site">
    From the dashboard, go to **Sites** → **New Site**. Enter a hostname — the domain your form will actually run on.
  </Step>

  <Step title="Copy the Site Key">
    Once created, the site's **Sitekey** is shown on its settings page.
  </Step>

  <Step title="Get your Secret Key">
    Go to **Settings** → **API Keys** (a Secret Key is created automatically with your account, shared across sites unless you generate a dedicated one per site).

    <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 **hCaptcha**, 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 hostname mismatch between what you entered in step 2 and where the form is actually embedded.
