Docs

Captcha

The Captcha Plugin integrates bot protection into your Better Auth system by adding captcha verification for key endpoints. This plugin ensures that only human users can perform actions like signing up, signing in, or resetting passwords. Two providers are currently supported: Google reCAPTCHA and Cloudflare Turnstile.

Installation

Add the plugin to your auth config

auth.ts
import { betterAuth } from "better-auth";
import { captcha } from "better-auth/plugins";
 
export const auth = betterAuth({
    plugins: [ 
        captcha({ 
            provider: "cloudflare-turnstile", // or "google-recaptcha" //
            secretKey: process.env.TURNSTILE_SECRET_KEY!, 
        }), 
    ], 
});

Add the captcha token to your request headers

Add the captcha token to your request headers for all protected endpoints. This example shows how to include it in a signIn request:

await authClient.signIn.email({
    email: "user@example.com",
    password: "secure-password",
    fetchOptions: { 
        headers: { 
            "x-captcha-response": turnstileToken, 
        }, 
    },
});

How it works

The plugin acts as a middleware: it intercepts all POST requests to configured endpoints (see endpoints in the Plugin Options section).

it validates the captcha token on the server, by calling the captcha provider's /siteverify.

  • if the token is missing, gets rejected by the captcha provider, or if the /siteverify endpoint is unavailable, the plugin returns an error and interrupts the request.
  • if the token is accepted by the captcha provider, the middleware returns undefined, meaning the request is allowed to proceed.

Plugin Options

  • provider (required) Your captcha provider. Supported values are cloudflare-turnstile and google-recaptcha.
  • secretKey (required) Your captcha provider secret key used for the server-side validation of captcha tokens.
  • endpoints (optional) An array of paths where captcha validation is enforced. Defaults to: ["/sign-up", "/sign-in", "/forget-password"].
  • siteVerifyURLOverride (optional) Overrides the endpoint URL for the captcha verification request.

On this page