Skip to main content

Verification sessions

A verification session ties one end user's document check, liveness check and face match together and returns a single decision. Use it when you need to know that the person holding the phone is the person on the document, not just that each check passed on its own.

Flow​

  1. Your server calls POST /v1/verifications with a secret key and the customer_ref of the person being verified. The response is the verification (vf_…) plus a session token (dv_tok_…) bound to it.
  2. Your app uses that token to call POST /v1/ocr (front and back of the document), then POST /v1/fraud/detect with the same image files byte for byte, then POST /v1/liveness/check, exactly as it would for standalone checks. Each result is recorded as a step of the verification. A fraud check sent before the scan, or on other images (including a dropped or added back), is refused with 400 validation_error before any analysis or billing.
  3. The platform compares the document portrait with the frame the liveness check scored, on the server, and decides. Your app never uploads a selfie for matching.
  4. Your server polls GET /v1/verifications/{id} for the decision. A verification.completed event is published for it as well; see Webhooks for which events can be subscribed to today.

The standalone endpoints keep working unchanged for integrations that only need one check.

Steps and decision​

StepCompleted whenFails when
documentOCR is eligible and a fraud check on the scanned images has run with a clean or needs_review decisionthe fraud decision is fraudulent
livenessis_live is trueis_live is false, with the liveness reason as the reason code
matchthe document portrait and the scored liveness frame agree at or above the tenant's face_match_thresholdthey do not, or one side has no usable face embedding

The decision is made as soon as it is determined:

OutcomeWhen
rejectedfraud said fraudulent on any scan in the verification; liveness failed and no attempts remain; the face did not match and no attempts remain
reviewfraud said needs_review or the fraud memory found a collision on any scan (unless the policy lets that through); always when the match could not be computed
approvedevery required step completed and the faces match

A liveness or match failure with attempts left keeps the verification pending, so the app can ask the user to try again. A verification is closed once decided; further calls with its token return 409 verification_closed, and calls for an expired or unknown verification return 404 not_found.

Scanning the document again replaces the document step, and the new scan needs its own fraud check. A needs_review, fraudulent or collision verdict from any scan still counts, even one that arrives after the re-scan; a retake verdict does not.

Policy​

Defaults come from your tenant configuration and can be overridden per verification in the create request:

{
"customer_ref": "cust-42",
"policy": {
"required_steps": ["document", "liveness", "match"],
"liveness_mode": "challenge",
"max_liveness_attempts": 2,
"review_blocks_approval": true
}
}
FieldDefaultNotes
required_steps["document", "liveness", "match"]Which steps the decision waits for.
liveness_modechallengepassive, burst or challenge. Enforced: a liveness call in another mode is a validation_error before any processing.
max_liveness_attempts21 to 5. Liveness or match failures beyond this close the verification as rejected.
review_blocks_approvaltrueWhether a needs_review fraud decision or a fraud-memory collision holds the verification in review instead of approving. It never approves a verification whose face match could not be computed, and never overrides fraudulent.

The token returned by POST /v1/verifications is a normal session token (see Authentication) bound to the verification, so client code that already takes a dv_tok_… works unchanged.

Retention and billing​

A verification record is kept for 90 days after its session token expires, whatever its outcome. Each step bills its own feature exactly as the standalone call does; the verification object itself is free.