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

# CAPTCHA provider configuration

> Use a captcha option for verifyngo and even configure multiple providers, so visitors can switch between them.

The point of verifyngo is to add a little friction upon a human's visit, so any random bot has to do the same, which many don't. verifyngo allows the setting of several captcha providers.

## Available providers

* `cap`
* `turnstile`
* `hcaptcha`
* `slider`

## Choosing your provider

Set the `provider` field to the name of the provider you want to use by default. Then fill in the configuration block that matches that provider name. The sections below show the exact fields for each option.

> [tab] Cap
>
> Cap is a self-hosted CAPTCHA server. You install and run it yourself, so challenge traffic goes through your own infrastructure.
>
> ```json theme={null}
> {
>   "provider": "cap",
>   "cap": {
>     "api_url": "https://captcha.example.com",
>     "verify_url": "http://127.0.0.1:3000",
>     "site_key": "your-cap-site-key",
>     "secret_key": "your-cap-secret-key",
>     "widget_script_url": ""
>   }
> }
> ```
>
> **cap.api\_url** `string` *required*
>
> The public URL of your Cap instance. The visitor's browser loads the widget script and submits the challenge from this address, so it must be reachable from the internet.
>
> **cap.verify\_url** `string`
>
> The URL verifyngo uses internally to verify a submitted token. Because this call happens server-side, you can point it at a local or internal address (e.g. `"http://127.0.0.1:3000"`) to avoid an extra round-trip through the internet. If left empty, verifyngo falls back to `api_url`.
>
> **cap.site\_key** `string` *required*
>
> The site key for your Cap instance. You'll find this in your Cap server's admin panel.
>
> **cap.secret\_key** `string` *required*
>
> The secret key for your Cap instance. Keep this value private — it is used to verify tokens server-side.
>
> **cap.widget\_script\_url** `string`
>
> An optional URL to load the Cap widget script from. Leave it empty to use the default Cap CDN (`https://cdn.jsdelivr.net/npm/@cap.js/widget`). Set this if you self-host the widget script alongside your Cap server.

> [tab] Turnstile
>
> Cloudflare Turnstile is a managed CAPTCHA service. You manage your keys from the Cloudflare dashboard.
>
> ```json theme={null}
> {
>   "provider": "turnstile",
>   "turnstile": {
>     "site_key": "your-turnstile-site-key",
>     "secret_key": "your-turnstile-secret-key"
>   }
> }
> ```
>
> **turnstile.site\_key** `string` *required*
>
> Your Turnstile site key. Find this in the Cloudflare dashboard under **Turnstile** → your site → **Site Key**.
>
> **turnstile.secret\_key** `string` *required*
>
> Your Turnstile secret key. Find this in the Cloudflare dashboard under **Turnstile** → your site → **Secret Key**. Keep this value private.

> [tab] hCaptcha
>
> hCaptcha is a managed CAPTCHA service. You manage your keys from the hCaptcha dashboard.
>
> ```json theme={null}
> {
>   "provider": "hcaptcha",
>   "hcaptcha": {
>     "site_key": "your-hcaptcha-site-key",
>     "secret_key": "your-hcaptcha-secret-key"
>   }
> }
> ```
>
> **hcaptcha.site\_key** `string` *required*
>
> Your hCaptcha site key. You can find this on your hCaptcha dashboard at [hcaptcha.com](https://www.hcaptcha.com) under **Sites**.
>
> **hcaptcha.secret\_key** `string` *required*
>
> Your hCaptcha secret key. You can find this in your hCaptcha account settings. Keep this value private.

> [tab] Slider
>
> For a very privacy-friendly use case, users can solve a slider puzzle. It is a self-contained, JavaScript-free challenge. Every request gets a procedurally generated "particle" scene (no external assets) with a target slot cut into it, plus a matching puzzle piece rendered as the native range-input thumb. The visitor drags the piece to line it up with the slot and submits a plain HTML form, the server compares the submitted position against the stored answer.
>
> ```json theme={null}
> "slider": {
>   "enabled": true,
>   "tolerance": 8,
>   "ttl": "10m",
>   "max_challenges": 5000,
>   "width": 320,
>   "height": 120
> }
> ```
>
> * `enabled` — makes the provider selectable (as the default or via the switcher)
> * `tolerance` — allowed deviation in pixels between the answer and the submitted position (default 8)
> * `ttl` — how long a generated challenge stays valid before it expires (default 10m)
> * `max_challenges` — cap on pending challenges held in memory (default 5000)
> * `width`/`height` — rendered canvas size in pixels (default 320x120)
>
> Each challenge is single-use and only valid for its TTL. Answers are kept in memory; with a multi-instance deployment, sticky sessions (or a shared store) are required.
>
> Because the scene is served as a data URI, make sure the challenge page CSP allows `data:` images. The default CSP already does; if you override `cap.csp`, keep `img-src ... data:`.

## Configuring multiple providers

You can fill in more than one provider block in the same `config.json`. The `provider` field controls which one is shown first — the others act as alternatives. When verifyngo detects that more than one provider is fully configured, it displays a "switch provider" link on the challenge page. Visitors can click it to switch to a different provider if the current one is unavailable or blocked for them.

```json theme={null}
{
  "provider": "cap",
  "cap": {
    "api_url": "https://captcha.example.com",
    "verify_url": "http://127.0.0.1:3000",
    "site_key": "your-cap-site-key",
    "secret_key": "your-cap-secret-key",
    "widget_script_url": ""
  },
  "turnstile": {
    "site_key": "your-turnstile-site-key",
    "secret_key": "your-turnstile-secret-key"
  }
}
```


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.