# `TURNSTILE_FAILED` (HTTP 403): the publishable key requires a Cloudflare Turnstile token

The key was created with a Turnstile site key and secret, and the lookup carried no token or one Cloudflare did not confirm.

A Turnstile-protected key needs a fresh turnstile_token with every lookup; tokens are single-use, so one cannot be reused across lookups. Nothing is billed for a refused lookup.

The form widget handles all of this when its script tag carries data-turnstile-site-key: it renders an invisible widget and fetches a token before each lookup.

**What to do.** Use the widget's data-turnstile-site-key attribute, or, with your own client, obtain a token from Turnstile before each request and send it as turnstile_token. A proxy in front of the endpoint must forward the token.

```json
{
    "success": false,
    "error": {
        "code": "TURNSTILE_FAILED",
        "message": "This publishable key requires a valid Cloudflare Turnstile token with every lookup.",
        "request_id": "req_01m1kgdm4xngzmbmff68g94w0c"
    }
}
```

Reference: https://spaw.co/docs/errors/TURNSTILE_FAILED
