Overview
Warnings on the liveness report flag every condition Didit observed while running the liveness check. They land in thewarnings[] array on each item of liveness_checks[] (see Liveness report), with feature set to "LIVENESS". Each entry follows the shared warning object shape: feature, risk, additional_data, log_type, short_description, long_description, node_id.
Every warning has three layers:
- The
riskcode — a stable identifier you can match on in your code (the codes listed below). - The
log_type— one ofinformation,warning, orerror. Auto-decline risks always carryerror. For configurable risks it is derived from the configured action: No action →information, Review →warning, Decline →error. For threshold-driven risks (LOW_LIVENESS_SCORE,LOW_FACE_QUALITY) it iserrorwhen the value crosses the decline threshold andwarningwhen it only crosses the review threshold. - The decision impact — the same routing drives the liveness report’s
status: a Review action moves it toIn Review, a Decline action (or any auto-decline risk) toDeclined, and No action leaves it untouched.
PASSIVE (multiple-faces, quality, and luminance checks). The tables below list the full set of liveness risk codes and their severities — no other liveness risk codes exist.
Auto-decline conditions
The following risks always force the liveness report (and the session) toDeclined, with log_type: "error":
When
NO_FACE_DETECTED fires, LOW_LIVENESS_SCORE is suppressed (there is no face to score).
Configurable verification settings
In the Didit console, liveness risks are grouped under the following workflow settings:Warnings produced
Core liveness
Capture channel integrity
Injection-attack signals reported by the client at capture time. Unlike presentation attacks (an artefact held in front of a real camera), these describe the camera feed itself being replaced or intercepted. Each is configurable per workflow and defaults to no action, so enabling the feature changes no decisions until you opt in.Browsers expose no OS-level camera-source attestation to any vendor, so on web these signals are corroborating evidence rather than proof. On web, a verdict of
null means not determined (device labels are unavailable until camera permission is granted) and never fires a risk.Cross-session face matching
For matches against imported faces or list-entry faces (which have no session), the
*_session_id, *_session_number, and api_service values in additional_data are null.
Faces belonging to the same user (same vendor_data, or the same vendor user when available) are excluded from the entire index search — both duplicate detection and blocklist screening. Match precedence is: blocklist exact → allowlist exact → duplicate exact → blocklist possible → allowlist possible → duplicate possible — only one of these six codes appears per report.
Passive liveness quality (only when method = "PASSIVE")
LOW_FACE_LUMINANCE and HIGH_FACE_LUMINANCE are mutually exclusive — the luminance is either below the minimum or above the maximum, never both.
Age estimation (adaptive workflows and AGE_ESTIMATION nodes)
Exact description strings
The API returns these exactshort_description and long_description strings for each risk:
Standalone passive liveness API
The standalone Liveness API reuses the same risk codes with a few behavioral differences:NO_FACE_DETECTEDandLOW_LIVENESS_SCOREare mutually exclusive — the score check only runs when a face was found.LOW_LIVENESS_SCOREfires against the request’sface_liveness_score_decline_threshold(default 30) and always carrieslog_type: "error".POSSIBLE_FACE_IN_BLOCKLISTis treated as a decline (log_type: "error") instead of review.MULTIPLE_FACES_DETECTEDcarrieslog_type: "warning", while the duplicate-face risks stay informational. Onlyerror-level warnings flip the standalone response’sstatustoDeclined.- Standalone warning entries include
featurebut nonode_id.
Examples
Auto-decline on detected attack
Configurable warnings on a passive capture
Duplicate face with payload
log_type: "warning" and the liveness report’s status is In Review. With the default (No action) it would carry log_type: "information" instead. api_service is null because the matched face came from a workflow session, not a standalone API call.
Warning types
Each risk is assigned a severity based on your application’s configuration. The three severities are:Related
- Liveness report — full report schema and statuses.
- Face match warnings — companion 1:1 face match warnings.
- Webhooks —
session.status.updatedcarries the warnings as soon as the liveness step finishes. - Data models — Liveness check — canonical schema with every field.
- Data models — Warning object — the shape of every entry in
warnings[].