Skip to main content
POST
Siteverify endpoint
Call this endpoint from your server before performing the protected action. A browser callback only supplies a token.
JSON and form-encoded bodies use the same fields. Keep the secret on your server.

Request

Set the policy and expected values in your backend. Never copy them from the submitted form. The widget’s data-escalate and data-mode control its presentation; a browser can change them. Use policy: "challenge" with data-mode="challenge". Use reject_concealed: true with data-escalate-concealed="true" when your action requires that check. With policy: "report", success means the proof verified; your code must then evaluate verdict.

Response

Single use

Each probe or completed ceremony supplies one single-use proof. Repeating the browser’s token request does not create another use or extend its expiry. Reusing it returns timeout-or-duplicate. A retry succeeds only with the same token, idempotency_key, policy, and expected context as the first successful request. A mismatch does not consume the proof. An expired proof cannot be retried. Make the protected action idempotent too. Store the attempt ID under a unique constraint with the account creation or other write. A successful verification retry must return the existing action result.

Failures

Verification failures use HTTP 200. Check success === true, not just the HTTP status. A 429 includes retry-after in seconds. On a timeout, network error, or failed verification, keep the action pending or reject it. Do not continue as if verification passed.

Test secret

hrtc_sk_00000000000000000000000000000000 verifies only the always-pass test site key. It returns test: true and allows repeated verification. Test keys check your integration, not the measurement or ceremony policy.