Verification modes
VerifyHuman is one assurance ladder: a zero-JS server floor, an on-page silent check, and a camera step-up — you enter at the rung your assurance need and page access allow. Invisible by default; friction only when it's earned.
There are two axes. Where verification runs (server-to-server, or a widget on the respondent's page) and, for the widget, how hard it verifies (invisible / captcha / standard). This page lists every mode, what it sees, and the exact way to integrate it.
Pick a mode
| If you… | Mode | How you integrate it |
|---|---|---|
| can't add code to the respondent's page (panel / supply, server-to-server only) | Server-Side | one HTTP call — POST /api/v1/lite/score |
| want a silent, no-friction check on the page, no camera | Invisible | SDK mount with widgetMode: 'invisible' |
| want a quick biometric proof (~2–3 s hidden camera) | Captcha | SDK mount with widgetMode: 'captcha' |
| want the strongest proof — full camera, liveness, challenges, uniqueness | Standard | SDK mount with widgetMode: 'standard' (the default) |
| a camera mode couldn't open the camera | device-only | automatic fallback — nothing to wire |
The ladder
L3 Active challenges (blink / smile / turn) ← STANDARD (when passive isn't enough)
L2 Passive camera: liveness + uniqueness ← CAPTCHA (quick) · STANDARD · step-up [BIOMETRIC]
───────────────────────────────────────────── step up only when the floor is uncertain
L1 <15KB probe: device signals, behavioral, ← INVISIBLE = L0 + L1
CDP/stealth, pointer entropy (no camera)
L0 Server floor: network / ASN / IP reputation ← EVERY mode, always. Zero-JS, calibrated.
· device reputation · velocity · dedup ·
· history · server behaviorEvery verification — including a full camera one — is scored by the server floor (L0) first. The camera provides the one thing nothing else can: proof a live, present, unique human is operating the session. Everything else is the shared floor beneath it.
Server-Side (no page code)
A stateless server-to-server scoring API you call once per respondent, where a legacy quality vendor (GRL / Research Defender) used to run. No camera, no client JavaScript, no PII stored. It returns a 0–100 risk score and an allow / review / block recommendation from network / device / velocity / duplicate / behavior / history signals.
POST https://vhuman.riwi.com/api/v1/lite/score
Authorization: Bearer <project API key>
Content-Type: application/json
{ "sessionId": "<your-id>", "clientIp": "<respondent-ip>",
"userAgent": "<respondent-ua>", "sourceId": "<your-supply-source>",
"studyId": "<your-questionnaire-id>" } // optional; per-study duplicate scope
// → read response.recommendation (allow | review | block | step_up)Pick it when you can't put code on the respondent's page, want zero friction, and a reputation-grade verdict (not biometric proof) is enough. The full field list, enum reference, identity-hashing spec, per-source calibration, and the evidence feedback loop are in the Server-Side scoring API reference — or manage the project over MCP.
How it's configured: a project's deploymentType selects the surface — fraud_gate for Server-Side (this mode, no page code) vs widget (the default, the SDK on the page). Set it in the dashboard, over MCP, or via PATCH /projects/{id}. Within widget, widgetMode picks how hard the on-page widget verifies (below).
Invisible / Captcha / Standard (the widget)
All three run the SDK on the respondent's page and differ only by widgetMode. Wiring for every path (React, Next.js, HTML drop-in, vanilla TS) is in the SDK guide; this is the summary.
widgetMode | Respondent sees | Signals |
|---|---|---|
invisible | Nothing. Runs silently. Camera never opens (unless escalateOnSuspicion). | Server floor + on-page probe: device, behavioral, CDP/stealth, pointer entropy. No camera. |
captcha | One-click / brief “verifying…” badge (~2–3 s). Camera runs hidden. | Above + quick passive liveness + face presence. |
standard | Full camera with face guide; passive liveness + active challenges when needed. | Above + full liveness, anti-spoof, biometric face-uniqueness. |
Minimal wiring
// Managed (npm: import { VH } from '@verifyhuman/sdk'; CDN: window.VH)
const result = await VH.mount("#vh", {
siteKey: "YOUR_SITE_KEY",
widgetMode: "invisible", // 'invisible' | 'captcha' | 'standard'
});
// React
import { VerifyHuman } from "@verifyhuman/sdk/react";
<VerifyHuman siteKey={SITE_KEY} widgetMode="captcha" onVerify={(t) => ...} />The widgetMode option / prop overrides the per-project default set in the dashboard. A pure HTML data-sitekey drop-in has no data-widget-mode attribute, so it takes the mode from the project config — use VH.mount or <VerifyHuman> to choose it from code. See the three layers of “mode” for the full precedence rules.
device-only (automatic fallback)
Not a mode you choose. When a camera mode can't open the camera (blocked WebView, denied permission, model load failure), the flow completes without the camera instead of dead-ending — scored by the server floor, plus behavioral evidence if the widget collected any. You can tell it apart on the result (unifiedVerdict.assuranceLevel reports device_only or behavioral instead of biometric) and set a minimum-assurance policy to reject it. See In-app browsers & camera for the recovery ladder and the assurance taxonomy.
Reading the verdict — one vocabulary
Whatever mode you run, the normalized answer is allow / review / block plus an assurance tier.
- Server-Side → read
recommendation(allow·review·block·step_up).verdictClass(human/fraud/verified_agent/unknown) classifies who the actor is, separately from the action. - Widget → read
unifiedVerdict.verdict(allow/review/block) for the same cross-mode band, orstatus(pass/fail) for the local widget outcome.unifiedVerdict.assuranceLevel(none/device_only/behavioral/biometric) tells you which ladder rung the verdict was reached at.
The widget maps its PASS / FAIL / CHALLENGE_REQUIRED decision onto the same allow/review/block words the Server-Side API uses (PASS → allow, CHALLENGE_REQUIRED → review, FAIL → block), so you only ever need one vocabulary for the answer. step_up (Server-Side only) is a review that specifically recommends escalating to a biometric check.