Biometric Liveness

Veriff Biometric Liveness solution ensures that the biometric data being captured is from a live person, significantly reducing the risk of fraud. This is a one-off verification, the end-user's data is not stored for re-verification purposes. The system analyses the images, verifies the end-user and returns the decision.

It is available via API, web flow, and native SDKs.

A separate integration is needed to do this verification, please contact your solutions engineer for info and configuration.


Prerequisites

  1. Your Solutions Engineer has set up a separate integration for you

  2. You have configured the decision webhook to get responses from Veriff (see the Webhooks section for info)

  3. If using the API, you are ready to send Veriff additional device/session data collected about the end-user

  4. Veriff strongly recommends that you create and send us the endUserId


Flow overview

The flow is a bit different, depending on the method you are using to verify your end-users with Veriff.

Use via SDKs

  1. Generate a verification session using the API keys and the baseURL of your Biometric Liveness integration (check the POST /sessions[↗] endpoint in the API reference)

  2. Capture end-user’s face images with Veriff’s SDKs

    1. Send the end-user through the verification flow to capture the face image (using the preferred Veriff SDK)

    2. You need the session URL generated in step 1 to use the SDKs (found in response payload as verification.url)

  3. Session will be submitted automatically once the end-user takes and submits necessary images of their face

  4. Receive the results from Veriff via decision webhook

Use via API

  1. Generate an authentication session using the API keys and the baseURL of your Biometric Liveness integration (check the POST /sessions[↗] endpoint in the API reference)

    1. Veriff strongly recommends you create and send the endUserId

  2. Upload the device/session data via POST sessions/{sessionid}/collected-data[↗]

  3. Use your face-capturing method, or prepare previously collected end-user face images

  4. Upload the end-user's face image via the POST /sessions/{sessionId}/media[↗] call

    1. Specify context parameter as face

  5. Patch session status to submitted status using PATCH /sessions/{sessionId}[↗] call

    1. Wait for Veriff to verify the end-user

    2. Check the decision data and/or session related info from the decision webhook and/or query the data from the GET sessions/{sessionId}/decision[↗] endpoint.


Find decision and session results

You can get the data from three sources:

  • Receive the decision webhook

  • Query the results via GET sessions/{sessionId}/decision

  • View the session in Veriff Customer Portal

Webhook payload

Below is an explanation and a sample of a decision webhook payload for a Biometric Liveness session. The decision webhook is used for many purposes, to find more info about it, see the decision webhook documentation.

Sample request

{
  "status": "success",
  "verification":{
      "id":"12df6045-3846-3e45-946a-14fa6136d78b",
      "attemptId":"c6cab5b0-c506-47a6-922d-6ae3b72ca172",
      "vendorData":null,
      "endUserId":"a1b2c35d-e8f7-6d5e-3cd2-a1b2c35db3d4",
      "status":"approved",
      "code":9001,
      "reason":null,
      "reasonCode":null,
      "decisionTime":"2025-01-05T12:55:01.232923Z",
      "acceptanceTime":"2025-01-05T07:18:36.916Z",
      "person":{
          "firstName":null,
          "lastName":null,
          "dateOfBirth":null,          
          "gender":null,
          "nationality":null,
          "idNumber":null,
          "yearOfBirth":null,
          "placeOfBirth":null,
          "pepSanctionMatch":null,
          "citizenship":null
      },
      "document":{
          "number":null,
          "type":null,
          "country":null,
          "state":null,
          "validUntil":null,
          "validFrom":null
      },
      "additionalVerifiedData":{},
      "comments":[],
      "riskLabels":[]
  },
  "technicalData": {
      "ip": "186.153.67.122"
  }
}

Response properties explained

  • status: string Status of the response

  • verification: object Verification request decision object. null if decision is not available yet

    • id: string UUID v4 which identifies the verification session

    • attemptId: string UUID v4 of the attempt which received a status (as shown in verification.status field)

    • vendorData: string | null The unique identifier that you created for your end-user. null if not specified

    • endUserId: string | null The UUID that you created for your end-user. null if not specified

    • status: string Verification status, one of approved, declined, resubmission_requested, review, expired, abandoned

    • code: integer Verification session decision code, one of 9001, 9102, 9103, 9104, 9121. For more info, see the verification session decision codes

    • reason: string | null Reason why the verification failed

    • reasonCode: integer | null Reason code of the failed verification. For more info, see the possible codes for a failed verification

    • decisionTime: string Timestamp of the decision, represented as UTC YYYY-MM-DDTHH:MM:SS.SSS+Timezone Offset (ISO 8601)

    • acceptanceTime: string Timestamp of the session generation, represented as UTC YYYY-MM-DDTHH:MM:SS.SSS+Timezone Offset (ISO 8601)

    • person: object Data about the verified person

      • firstName: string | null Person's first name as written on the document

      • lastName: string | null Person's last name as written on the document

      • dateOfBirth: string Date of birth, represented as YYYY-MM-DD

      • gender: string | null Person’s gender, represented as M or F, or null if not present

      • nationality: string | null Person’s nationality, represented as ISO 3166 alpha-2 or alpha-3 number

      • idNumber: string | null National identification number

      • yearOfBirth: string | null Person’s year of birth, represented as YYYY

      • placeOfBirth: string | null Person’s place of birth

      • pepSanctionMatch: string | null Legacy field, may return incorrect result, should be ignored

      • citizenship: null Deprecated, always returns null

    • document: object Verified document

      • number: string | null Document number, [a-zA-Z0-9] characters only

      • type: string | null Document type, one of PASSPORT, ID_CARD, RESIDENCE_PERMIT, DRIVERS_LICENSE, VISA, OTHER. For more info, see the Supported document types for IDV article

      • country: string | null Document issuing country, represented as ISO 3166 alpha-2 code

      • state: string | null Document issuing state, represented as ISO 3166 alpha-2 or alpha-3 code

    • additionalVerifiedData: object Data that has been optionally verified for the session. Optional, depending on the integration

    • comments: array (Deprecated) Always returns empty []

    • highRisk: boolean (Deprecated) Marked if session was considered high risk or not

  • technicalData: object Technical data object

    • ip: string | null IP of the device from which the verification was made

API call

You can use the GET sessions/{sessionId}/decision[↗] endpoint to get the decision data.

Below is an explanation and a sample of the API call payload for a Biometric Liveness session. This endpoint is used for many purposes, to find more info about it, see the the GET sessions/{sessionId}/decision[↗] documentation.

Sample response

{
  "status": "success",
  "verification":{
      "id":"12df6045-3846-3e45-946a-14fa6136d78b",
      "attemptId":"c6cab5b0-c506-47a6-922d-6ae3b72ca172",
      "vendorData":null,
      "endUserId":"a1b2c35d-e8f7-6d5e-3cd2-a1b2c35db3d4",
      "status":"approved",
      "code":9001,
      "reason":null,
      "reasonCode":null,
      "decisionTime":"2025-01-05T12:55:01.232923Z",
      "acceptanceTime":"2025-01-05T07:18:36.916Z",
      "person":{
          "firstName":null,
          "lastName":null,
          "dateOfBirth":null,          
          "gender":null,
          "nationality":null,
          "idNumber":null,
          "yearOfBirth":null,
          "placeOfBirth":null,
          "pepSanctionMatch":null,
          "citizenship":null
      },
      "document":{
          "number":null,
          "type":null,
          "country":null,
          "state":null
      },
      "additionalVerifiedData":{},
      "comments":[],
      "riskLabels":[]
  },
  "technicalData": {
      "ip": "186.153.67.122"
  }
}

Response properties explained

  • status: string Status of the response

  • verification: object Verification request decision object. null if decision is not available yet

    • id: string UUID v4 which identifies the verification session

    • attemptId: string UUID v4 of the attempt which received a status (as shown in verification.status field)

    • vendorData: string | null The unique identifier that you created for your end-user. null if not specified

    • endUserId: string | null The UUID that you created for your end-user. null if not specified

    • status: string Verification status, one of approved, declined, resubmission_requested, review, expired, abandoned

    • code: integer Verification session decision code, one of 9001, 9102, 9103, 9104, 9121. For more info, see the verification session decision codes

    • reason: string | null Reason why the verification failed

    • reasonCode: integer | null Reason code of the failed verification. For more info, see the possible codes for a failed verification

    • decisionTime: string Timestamp of the decision, represented as UTC YYYY-MM-DDTHH:MM:SS.SSS+Timezone Offset (ISO 8601)

    • acceptanceTime: string Timestamp of the session generation, represented as UTC YYYY-MM-DDTHH:MM:SS.SSS+Timezone Offset (ISO 8601)

    • person: object Data about the verified person

      • firstName: string | null Person's first name as written on the document

      • lastName: string | null Person's last name as written on the document

      • dateOfBirth: string Date of birth, represented as YYYY-MM-DD

      • gender: string | null Person’s gender, represented as M or F, or null if not present

      • nationality: string | null Person’s nationality, represented as ISO 3166 alpha-2 or alpha-3 number

      • idNumber: string | null National identification number

      • yearOfBirth: string | null Person’s year of birth, represented as YYYY

      • placeOfBirth: string | null Person’s place of birth

      • pepSanctionMatch: string | null Legacy field, may return incorrect result, should be ignored

      • citizenship: null Deprecated, always returns null

    • document: object Verified document

      • number: string | null Document number, [a-zA-Z0-9] characters only

      • type: string | null Document type, one of PASSPORT, ID_CARD, RESIDENCE_PERMIT, DRIVERS_LICENSE, VISA, OTHER. For more info, see the Supported document types for IDV article

      • country: string | null Document issuing country, represented as ISO 3166 alpha-2 code

      • state: string | null Document issuing state, represented as ISO 3166 alpha-2 or alpha-3 code

    • additionalVerifiedData: object Data that has been optionally verified for the session. Optional, depending on the integration

    • comments: array (Deprecated) Always returns empty []

    • highRisk: boolean (Deprecated) Marked if session was considered high risk or not

  • technicalData: object Technical data object

    • ip: string | null IP of the device from which the verification was made

View in Veriff Customer Portal

You can find the verification session related info in the Veriff Customer Portal, under the Webhooks tab.

See Review verification in Veriff Customer Portal about how to view the session info in the Veriff Customer portal


Status and reason codes

For an approved session, see the verification.code and verification.status parameters.

If the session was declined or resubmission_requested, you can find additional information by checking the verification.status, verification.code, verification.reason and verification.reasonCode data objects.

Table below lists some reason codes specific to Biometric Liveness sessions.

→ If you are seeing codes not listed in the table below, see the Granular Reason Codes article

Code

Description

105

Declined - Suspicious behaviour

106

Declined - Known fraud

201

Resubmission requested - Video and/or photos missing

204

Resubmission requested - Poor image quality

503

Declined - Attempted deceit

515

Declined - Attempted deceit, device screen used for face image

546

Declined - Face image quality insufficient

547

Declined - Face missing

603

Resubmission requested - Video missing

605

Resubmission requested - Face image missing

606

Resubmission requested - Face is not clearly visible


FAQ

Where can I query the media the end-user submitted during verification process?

It is possible to query the media the end-user submitted during the verification process via:

Data retention policies may apply.


Article versioning

Date

Description

Mar 28, 2025

Broken links fixed

Mar 12, 2025

Documentation published