Skip to content

Server-Side Verification API

The token your frontend receives can only be trusted after it's checked on the server. This endpoint is compatible with the reCAPTCHA / hCaptcha siteverify API (it accepts both JSON request bodies and form encoding) — when migrating from them, your backend usually only needs to change one URL. See the migration guide for a side-by-side walkthrough.

Endpoint

POST https://api.capcat.ai/<site-key>/siteverify
Content-Type: application/json

{ "secret": "<secret_key>", "response": "<captcha_token>" }
  • secret — the secret generated when you created the site in the console (shown only once, at creation or rotation);
  • response — the token produced by the frontend widget (the cap-token field in your form, or e.detail.token from the solve event).

A successful verification returns:

json
{ "success": true }

The token is single-use: it becomes invalid immediately after a successful verification, and replaying it returns a failure.

Examples in multiple languages

sh
curl "https://api.capcat.ai/<site-key>/siteverify" \
  -X POST \
  -H "Content-Type: application/json" \
  -d '{ "secret": "<secret_key>", "response": "<captcha_token>" }'
js
const { success } = await (
  await fetch("https://api.capcat.ai/<site-key>/siteverify", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ secret: "<secret_key>", response: "<captcha_token>" }),
  })
).json();

if (!success) throw new Error("CAPTCHA verification failed");
py
import requests

success = requests.post(
    "https://api.capcat.ai/<site-key>/siteverify",
    json={"secret": "<secret_key>", "response": "<captcha_token>"},
).json().get("success")
php
<?php
$ctx = stream_context_create([
  "http" => [
    "method" => "POST",
    "header" => "Content-Type: application/json",
    "content" => json_encode([
      "secret" => "<secret_key>",
      "response" => "<captcha_token>",
    ]),
  ],
]);
$data = json_decode(file_get_contents(
  "https://api.capcat.ai/<site-key>/siteverify", false, $ctx
), true);
var_dump($data["success"] ?? false);

Built on Cap (Apache 2.0)