Demo pages API
More
The public demo and CAPTCHA test pages: checking a token from one of their Cloudflare Turnstile widgets with Cloudflare's siteverify, and whether a request carried a Cloudflare clearance. Public, with no key or session; nothing here solves anything.
Every operation of the API reference is generated from the contract the API serves, version 0.1.0. Replace YOUR_API_KEY in the samples with your key.
Check for a Cloudflare clearance
GET/v1/demo/clearance
Says whether this request carried a cf_clearance cookie, the one Cloudflare sets once a challenge, or a Cloudflare Turnstile widget with pre-clearance, is passed, and whether it came through Cloudflare's network. The demo challenge pages call it from the browser, which sends the cookie that page scripts may not be able to read. The cookie's value is never read out, logged or kept, and only Cloudflare can say whether it is still valid. It needs no key or session. Requests have the budget per client address that public reads share. Never cached.
Authentication: None: anyone may call it, within a budget per client address where the description says so.
Responses
| Status | Meaning | Body |
|---|---|---|
| 200 OK | What the request carried. | DemoClearance (application/json) |
| 429 Too Many Requests | Too many requests from this address ( | Problem (application/problem+json) |
| 503 Service Unavailable | The budget could not be checked now ( | Problem (application/problem+json) |
| Any other status | An error, as RFC 9457 problem details. | Problem (application/problem+json) |
Error codes
rate_limited, service_unavailable. The errors reference says what each means, whether a retry helps and what it costs.
Sample
curl https://api.zerocaptcha.io/v1/demo/clearanceconst response = await fetch("https://api.zerocaptcha.io/v1/demo/clearance");console.log(response.status, await response.text());import requests
response = requests.get( "https://api.zerocaptcha.io/v1/demo/clearance", timeout=30,)print(response.status_code, response.text)Check a demo token
POST/v1/demo/verify
Asks Cloudflare's siteverify about a token from one of the demo pages' Cloudflare Turnstile widgets, with that widget's secret, and returns the verdict as it came: success, the hostname, the action, the cData and the error codes. Solves nothing: bring a token a widget gave, in a browser or through a task. A token passes siteverify once, within 300 seconds of the solve. It needs no key or session. A browser's request must send no Sec-Fetch-Site but same-origin or none (csrf_rejected). Checks have a budget per client address. The token is never logged or kept.
Authentication: None: anyone may call it, within a budget per client address where the description says so.
Request body
JSON: DemoVerification.
| Field | Type | Description |
|---|---|---|
token required | string | The token: the widget's |
widget required | DemoWidget | The demo widget the token came from. One of: |
Responses
| Status | Meaning | Body |
|---|---|---|
| 200 OK | Cloudflare's verdict, a failing one included. | DemoVerdict (application/json) |
| 403 Forbidden | A browser's request from another site ( | Problem (application/problem+json) |
| 422 Unprocessable Content | An unknown widget, or no token, or not one siteverify takes ( | Problem (application/problem+json) |
| 429 Too Many Requests | Too many checks from this address ( | Problem (application/problem+json) |
| 503 Service Unavailable | Cloudflare's siteverify did not answer, or this server does not serve the demo ( | Problem (application/problem+json) |
| Any other status | An error, as RFC 9457 problem details. | Problem (application/problem+json) |
Error codes
csrf_rejected, validation_failed, rate_limited, service_unavailable. The errors reference says what each means, whether a retry helps and what it costs.
Sample
curl -X POST https://api.zerocaptcha.io/v1/demo/verify \ -H "Content-Type: application/json" \ -d '{ "token": "token", "widget": "managed"}'const response = await fetch("https://api.zerocaptcha.io/v1/demo/verify", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ "token": "token", "widget": "managed" }),});console.log(response.status, await response.text());import requests
response = requests.post( "https://api.zerocaptcha.io/v1/demo/verify", json={ "token": "token", "widget": "managed", }, timeout=30,)print(response.status_code, response.text)