PHP

Copy sdk/php/PrivCaptcha.php into your project. It needs the cURL extension and nothing else.

Verify

require_once 'PrivCaptcha.php';

$result = PrivCaptcha::verify(
    getenv('PRIVCAPTCHA_SECRET'),
    $_POST['privcaptcha-response'] ?? '',
    $_SERVER['REMOTE_ADDR'] ?? null
);

if (!$result->success) {
    http_response_code(400);
    exit('captcha failed: ' . implode(',', $result->errorCodes));
}
PrivCaptcha::verify(
    string $secret,
    string $response,
    ?string $remoteIp = null,
    string $endpoint = PrivCaptcha::DEFAULT_ENDPOINT,
    int $timeout = 10
): PrivCaptchaResult

PrivCaptchaResult has success, challengeTs, hostname and errorCodes.

Fail-closed behaviour

A cURL failure, a non-200 status or an unparseable body sets success = false with errorCodes = ['verification-unavailable']. Peer verification stays on; do not disable it.

An empty $response returns missing-input-response without a network call.

Migrating

If you loaded one of the compatibility shims, your form still posts g-recaptcha-response or h-captcha-response. Keep reading whichever key you already use — only the secret and this call change.