Success
Require the verification response to explicitly indicate success.
Render the VettiGuard widget, receive a short-lived response, then call the private verification endpoint before processing the form, account, transaction, or API action.
The public site key identifies the policy. The action labels the business workflow. Neither the private secret nor trust decision belongs in the page.
<script src="https://vettiguard.com/assets/captcha.js?v=1785553816" data-brand-url="https://vettiguard.com" defer></script>
<form method="post" action="/register-account.php">
<!-- Your normal form fields -->
<div class="vettiguard-captcha"
data-sitekey="YOUR_SITE_KEY"
data-action="account-registration"
data-api-base="https://vettiguard.com/"></div>
<button type="submit">Create account</button>
</form>Forms are paused until a token is ready. You may also execute the check directly. A policy or invisible check can open the visual popup when the request needs stronger proof.
const token = await VettiGuard.execute(
document.querySelector('.vettiguard-captcha')
);
if (!token) {
throw new Error('Verification was not completed');
}Send the private secret, browser response, expected action, and—when safely resolved—the visitor IP. HTTP 200 means the request was processed, not necessarily accepted.
curl --silent --show-error --fail-with-body \ --request POST "https://vettiguard.com/api/v1/siteverify" \ --header "Content-Type: application/x-www-form-urlencoded" \ --data-urlencode "secret=vg_secret_replace_me" \ --data-urlencode "response=RESPONSE_TOKEN" \ --data-urlencode "remoteip=203.0.113.10" \ --data-urlencode "action=account-registration"
Require explicit success, an empty error list, the expected action and hostname, and an acceptable risk score before the protected operation.
{
"success": true,
"challenge_ts": "2026-07-30 21:42:18",
"hostname": "example.com",
"score": 0.82,
"score_threshold": 0.5,
"score_enforced": true,
"challenge_type": "visual",
"challenge_variant": "identify",
"action": "account-registration",
"error-codes": []
}Send the response token and private secret to /api/v1/siteverify. Then enforce success, expected action, hostname, and your minimum score.
$result = $verifier->verify(
$_POST['vettiguard-response'] ?? '',
$_SERVER['REMOTE_ADDR'] ?? null,
'account-registration'
);
if (!$result->isSuccess()
|| $result->action() !== 'account-registration'
|| $result->hostname() !== 'example.com'
|| $result->score() < 0.50) {
http_response_code(422);
exit('Verification failed.');
}
// Run the protected action only here.A successful widget animation is not enough. The backend response is the source of truth.
Require the verification response to explicitly indicate success.
Match the response to the exact form or operation being protected.
Confirm that the response originated from the expected site.
Check score_enforced; score-based integrations must apply their own action threshold.
Reject expired responses and ask the user to complete a new challenge.
Do not retry the same consumed token after business validation fails.
Open the exact implementation guidance you need, copy examples directly, and keep the packaged files as an offline reference only.
cURL for every platform, complete responses, error codes, replay rules, proxies, and fail-closed validation.
Challenge creation, solve payloads, visual assets, fallback requests, quotas, and site verification.
Quick-start integration, result methods, validation example, and the complete copyable verifier source.
POST /api/v1/challengePOST /api/v1/solvePOST /api/v1/siteverifyGET /healthThis action may affect your integration.