Skip to main content

Liveness Check

Overview​

The liveness check system verifies that a self-service user is a real person (not a photo or replay attack) using a challenge-response face-capture flow from the mobile SDK. Results — including the captured face image in Base64 — are persisted per user and are available for admin review.

There are five APIs across two roles:

CommandRolePurpose
SubmitLivenessCheckCommandCustomer (authenticated)Submit a successful liveness result (creates record)
UpdateLivenessCheckCommandCustomer (authenticated)Submit any result (successful or not) — used by SDK
CheckLivenessStatusQueryCustomer (authenticated)Check whether the current user has passed liveness
GetUserLivenessCheckQueryAdminGet full liveness record + face image for any user by ID
RetrieveLivenessChecksQueryAdminPaginated list of liveness records (filter by user/session)

All endpoints share the same base path: POST /api/BPMSelfService/commands/{CommandName}


1. Submit Liveness Check​

Endpoint: POST /api/BPMSelfService/commands/SubmitLivenessCheckCommand

Only successful checks are persisted

If isSuccessful is false, the command returns an error immediately. Use UpdateLivenessCheckCommand to record any outcome.

The selfServiceUserId is resolved automatically from the bearer token — do not include it in the payload.

Request Body​

{
"sessionId": "sdk-session-abc123",
"isSuccessful": true,
"imageBase64": "data:image/jpeg;base64,/9j/4AAQSkZJRgAB...",
"imagePath": "/uploads/liveness/abc123.jpg",
"metadata": {
"timestamp": 1742680800000,
"completedAt": "2026-03-22T14:00:00Z",
"verificationResult": true,
"sessionDuration": 4200,
"lightingValue": 0.93,
"challengeCount": 3,
"completedChallenges": ["BLINK", "SMILE", "TURN_LEFT"],
"challenges": ["BLINK", "SMILE", "TURN_LEFT"],
"finalCapture": {
"verificationResult": true,
"sessionDuration": 1100,
"lightingValue": 0.95
}
},
"imageMetadata": {
"verificationResult": true,
"sessionDuration": 900,
"lightingValue": 0.91
}
}

Parameters​

FieldTypeRequiredDescription
sessionIdstringYesUnique session identifier from the liveness SDK
isSuccessfulbooleanYesMust be true — failed checks are rejected
imageBase64stringNoBase64-encoded face capture image (with or without data URI prefix)
imagePathstringNoServer-side path if image was uploaded separately
metadataobjectNoChallenge + session metrics from the SDK
metadata.timestamplongNoUnix epoch milliseconds
metadata.completedAtstringNoISO 8601 datetime of completion
metadata.verificationResultbooleanNoSDK verification outcome
metadata.sessionDurationintegerNoDuration in milliseconds
metadata.lightingValuenumberNoLighting score (0–1)
metadata.challengeCountintegerNoNumber of challenges presented
metadata.completedChallengesstring[]NoChallenges the user completed (e.g. ["BLINK","SMILE"])
metadata.challengesstring[]NoAll challenges presented
metadata.finalCaptureobjectNoMetrics for the final face capture
imageMetadataobjectNoMetrics specific to the captured image

Response​

{
"isSuccessful": true,
"statusCode": "00",
"message": "Liveness check completed successfully.",
"data": {
"id": 42,
"sessionId": "sdk-session-abc123",
"isSuccessful": true,
"verificationResult": true,
"challengeCount": 3,
"completedAt": "2026-03-22T14:00:00Z",
"createdAt": "2026-03-22T14:00:05Z"
}
}

2. Update Liveness Check​

Endpoint: POST /api/BPMSelfService/commands/UpdateLivenessCheckCommand

Records any liveness outcome (successful or failed). This is the command the mobile SDK should call directly, as it accepts isSuccessful: false without rejecting the request.

Request Body​

Identical structure to SubmitLivenessCheckCommand but isSuccessful can be false.

{
"sessionId": "sdk-session-abc123",
"isSuccessful": false,
"metadata": {
"verificationResult": false,
"sessionDuration": 8000,
"lightingValue": 0.42,
"challengeCount": 3,
"completedChallenges": ["BLINK"]
}
}

Response​

{
"isSuccessful": true,
"statusCode": "00",
"message": "Liveness check recorded but verification was not successful.",
"data": {
"id": 43,
"sessionId": "sdk-session-abc123",
"isSuccessful": false,
"verificationResult": false,
"challengeCount": 3,
"completedAt": null,
"createdAt": "2026-03-22T14:05:00Z"
}
}

3. Check Liveness Status​

Endpoint: POST /api/BPMSelfService/commands/CheckLivenessStatusQuery

Lightweight check — returns whether the currently authenticated user has at least one successful liveness record on file. No body required.

Request Body​

{}

Response​

{
"isSuccessful": true,
"statusCode": "00",
"message": "Liveness check has been completed.",
"data": {
"HasCompletedLivenessCheck": true,
"LivenessCheckDate": "2026-03-22T14:00:00Z",
"SessionId": "sdk-session-abc123"
}
}

When the user has not completed liveness:

{
"isSuccessful": true,
"statusCode": "00",
"message": "Liveness check has not been completed.",
"data": {
"HasCompletedLivenessCheck": false,
"LivenessCheckDate": null,
"SessionId": null
}
}

4. Get User Liveness Check (Admin)​

Endpoint: POST /api/BPMSelfService/commands/GetUserLivenessCheckQuery

Admin only

This API requires an admin bearer token. It returns the full liveness record including the captured face image (ImageBase64) for display in the admin portal.

Request Body​

{
"userId": 1234
}
FieldTypeRequiredDescription
userIdlongYesThe SelfServiceUser.Id to look up

Response​

{
"isSuccessful": true,
"statusCode": "00",
"data": {
"UserId": 1234,
"EmailAddress": "customer@example.com",
"UserId2": "USR-00001234",
"FirstName": "Jane",
"LastName": "Doe",
"MiddleName": null,
"DisplayName": "Jane Doe",
"HasCompletedLivenessCheck": true,
"LivenessCheck": {
"Id": 42,
"SessionId": "sdk-session-abc123",
"IsSuccessful": true,
"VerificationResult": true,
"SessionDuration": 4200,
"LightingValue": 0.93,
"ChallengeCount": 3,
"CompletedChallenges": ["BLINK", "SMILE", "TURN_LEFT"],
"FinalCaptureVerificationResult": true,
"ImageBase64": "data:image/jpeg;base64,/9j/4AAQSkZJRgAB...",
"HasImage": true,
"ImagePath": null,
"ImageVerificationResult": true,
"CompletedAt": "2026-03-22T14:00:00Z",
"CreatedAt": "2026-03-22T14:00:05Z",
"DeviceInfo": "{\"userAgent\":\"...\",\"devicePlatform\":\"Android\",\"appVersion\":\"2.1.0\"}",
"ClientIp": "41.58.12.100"
}
}
}

When HasCompletedLivenessCheck is false, LivenessCheck will be null.

HasCompletedLivenessCheck Logic​

A user is considered to have completed liveness only when the latest record satisfies both:

  • IsSuccessful == true
  • VerificationResult == true

5. Retrieve Liveness Checks (Admin — Paginated)​

Endpoint: POST /api/BPMSelfService/commands/RetrieveLivenessChecksQuery

Paginated list of liveness check records. Useful for auditing or bulk review.

Request Body​

{
"selfServiceUserId": 1234,
"pageNumber": 1,
"pageSize": 20
}
FieldTypeRequiredDescription
preRegistrationIdlongNoFilter by pre-registration ID
selfServiceUserIdlongNoFilter by self-service user ID
sessionIdstringNoFilter by SDK session ID
pageNumberintegerNoPage number (default: 1)
pageSizeintegerNoPage size (default: 20)

SDK Integration Flow​