Last updated
Last updated
# Liveness Workflow — Callback Methods & Response Structure
## Overview
The liveness workflow provides callback methods to handle the result of liveness verification. The two primary callbacks are **`onComplete`** and **`onError`**.
By default, `onComplete` fires only when liveness passes — so you can treat it as a success callback. All failure scenarios are routed to `onError`.
## Usage
```js
onComplete: (data) => {
console.log('Completed', data);
},
onError: (data) => {
console.log('Error', data);
}
```
---
## Primary Callbacks
### `onComplete`
Called when liveness verification passes successfully. We recommend checking `code` and `liveImage` in the response for additional confirmation.
**Response structure:**
```js
{
"score": 0.266861,
"liveImage": true,
"message": "Selfie photo is a live photo",
"code": 1043,
"imgManipulationScore": 0.093356,
"transactionId": "fa581b84-6d90-9cdd-f073-18fd020be300",
"base64Image": "data:image/jpeg;base64,..."
}
```
**Color flash (smart liveness) response:**
When color flash is enabled, the response includes a `livenessScores` array with individual scores for each verification method:
```js
{
"score": 0.277815,
"liveImage": true,
"message": "Smart liveness success",
"code": 1043,
"transactionId": "2a58d634-d137-44c1-9527-cec61891e8df",
"base64Image": "data:image/jpeg;base64,...",
"attemptedTransactionIds": ["2a58d634-d137-44c1-9527-cec61891e8df"],
"livenessScores": [
{ "type": "passiveLiveness", "score": 0.171321 },
{ "type": "imageManipulation", "score": 0.093166 },
{ "type": "colorCaptcha", "score": 0.277815 }
]
}
```
**`attemptedTransactionIds`:**
If there were multiple retry attempts, an `attemptedTransactionIds` array is included containing the transaction IDs from all attempts. This field is only present when there are more than 1 attempt.
```js
{
"score": 0.266861,
"liveImage": true,
"message": "Selfie photo is a live photo",
"code": 1043,
"transactionId": "latest-txn-id",
"attemptedTransactionIds": ["first-attempt-txn-id", "second-attempt-txn-id", "latest-txn-id"],
"base64Image": "data:image/jpeg;base64,..."
}
```
---
### `onError`
Called when an error occurs during the liveness flow. This includes api errors, frontend errors (camera, network, timeout, user cancellation) and max retries exhausted.
**When `skipSelfieReviewScreen: false` (Default):**
- Liveness failures due to image quality or threshold are retried by the user — `onError` fires only when max retries are exhausted or when api fails due to system error or any unknown error, with the last API response included in the `response` field
- `onComplete` does NOT fire for failures — it only fires on success
**When `skipSelfieReviewScreen: true`:**
- Liveness failures due to image quality or threshold go to `onError` immediately since there is no review/retry screen and its the end of the flow. All other errors mentioned above also go to `onError`
**Network error:**
```js
{
"code": 40001,
"message": "Unable to proceed, please check your connection"
}
```
**Network timeout:**
```js
{
"code": 40002,
"message": "Unable to proceed due to network timeout, please check your connection"
}
```
**Token expired / unauthorized:**
```js
{
"code": 40003,
"message": "Unable to proceed, ensure authorization method is correct and token is not expired"
}
```
**Camera permission denied:**
```js
{
"code": 70001,
"message": "Unable to proceed, the functionality will not work without Camera permissions"
}
```
**Face detection model download failed:**
```js
{
"code": 70002,
"message": "Unable to proceed, failed to download face landmark models"
}
```
**Unsupported device/browser:**
```js
{
"code": 70003,
"message": "Unable to proceed, browser or device doesn't support this functionality"
}
```
**Camera not found:**
```js
{
"code": 70005,
"message": "Unable to proceed, No camera device found"
}
```
**Detection timeout:**
```js
{
"code": 70007,
"message": "Detection timed out"
}
```
**User cancelled (closed modal):**
```js
{
"code": 70008,
"message": "User cancelled liveness process by closing the modal"
}
```
When the user manually closes the modal after a liveness API failure, the error response includes the last liveness error details along with the selfie image:
```js
{
"code": 70008,
"message": "User cancelled liveness process by closing the modal",
"response": {
"score": -1,
"liveImage": false,
"message": "Detect Un-standardized Image Quality",
"code": 1051,
"transactionId": "d61f047d-3435-bf8c-2138-4b8a2fc05e87",
"base64Image": "data:image/jpeg;base64,..."
}
}
```
**Max retry exhausted:**
Includes the last liveness API response wrapped inside a `response` key:
```js
{
"code": 70010,
"message": "Maximum attempt to retry liveness has exhausted, Try again later",
"response": {
"score": -1,
"liveImage": false,
"message": "Detect Un-standardized Image Quality",
"code": 1051,
"transactionId": "d61f047d-3435-bf8c-2138-4b8a2fc05e87",
"base64Image": "data:image/jpeg;base64,..."
}
}
```
**Color flash upload error:**
```js
{
"code": 50006,
"message": "Unknown error occurred during color flash image upload, please try again later"
}
```
**Unknown error:**
```js
{
"code": 50005,
"message": "Unknown error occurred, please try again later"
}
```
#### Frontend Error Codes Reference
| Code | Description |
| ----- | ------------------------------------ |
| 40001 | Network offline |
| 40002 | Network timeout |
| 40003 | Token expired or unauthorized |
| 50005 | Unknown error |
| 50006 | Color flash image upload error |
| 70001 | Camera permission denied |
| 70002 | Face detection model download failed |
| 70003 | Unsupported device/browser |
| 70004 | Video frame processing failed |
| 70005 | No camera device found |
| 70006 | Image capture failed |
| 70007 | Face detection timeout |
| 70008 | User cancelled (closed modal) |
| 70009 | Camera failed to start |
| 70010 | Max retry attempts exhausted |
| 70011 | Virtual camera detected |
---
## Intermediate Callbacks (Optional)
### `onLivenessApiError`
Fired immediately when the liveness API call fails. Use this only if you need to react to API failures in real-time (e.g., logging, analytics). For handling the final outcome of the flow, use `onError` instead.
```js
onLivenessApiError: (data) => {
console.log('Liveness API error', data.code, data.message);
};
```
### `onSelfieCapture`
Called when a selfie is captured. Receives the base64 image string. Useful for custom processing or analytics before the liveness API is called.
```js
onSelfieCapture: (image) => {
// image is a base64 encoded JPEG string
console.log('Selfie captured', image);
};
```
## Key Fields Reference
| Field | Description |
| ------------------------- | ------------------------------------------------------------------------------------- |
| `code` | Response code. `1043` = liveness passed. Other codes indicate specific failures. |
| `liveImage` | `true` if liveness passed, `false` otherwise. **Always check this field.** |
| `score` | Liveness confidence score |
| `message` | Human-readable result description |
| `imgManipulationScore` | Image manipulation detection score |
| `transactionId` | Transaction ID of the latest attempt |
| `attemptedTransactionIds` | Array of all attempt transaction IDs. Only present when there were multiple attempts. |
| `base64Image` | Captured selfie image (base64 JPEG) |
| `livenessScores` | Array of individual scores per verification method (color flash only). Each entry has `type` and `score`. Types: `passiveLiveness`, `imageManipulation`, `colorCaptcha`. |
