Create Transaction
Opens a FaceAuthen transaction and returns the JWT token the Mobile SDK authenticates with. It also fixes the challenge level, the sanity options the verify step will run, and whether flash liveness is required.
Endpoint
POST /v1/create_transaction
Content-Type: application/json{
"user_id": "user_00000001",
"ref_id": "ref_00000001",
"level": 0,
"sanity_options": {
"mask_check": true,
"glasses_check": false
},
"enable_flash_liveness": false
}Parameters:
| Param | Type | Required | Default | Description |
|---|---|---|---|---|
user_id | string | Yes | — | The user ID. |
ref_id | string | Yes | — | The transaction reference ID. |
level | integer | No | 0 | The challenge level. Validated against the tenant's configured challenge settings — must be no greater than the number of configured verdict levels. Higher levels require more stringent face verification. |
sanity_options | object | No | — | Per-call toggles selecting which sanity checks the verification step runs. Keys are filtered against the server's allow-list; unlisted keys are ignored. |
enable_flash_liveness | boolean | No | false | When true and the tenant has flash-liveness colors configured, the server generates a shuffled color sequence and stores it on the transaction for the verify step. Silently ignored when the tenant has no colors configured. |
sanity_options keys
Allowed keys, each a boolean:
| Field | Type | Description |
|---|---|---|
image_type | bool | Check the input image is the correct type for this flow. |
occlusion_check | bool | Check the face is not occluded. |
eyes_check | bool | Check the eyes are open and visible. |
mask_check | bool | Check for a face mask. |
glasses_check | bool | Check for glasses. |
light_quality | bool | Check lighting quality. |
deepfake_check | bool | Check for synthetic or generated faces. |
supported_selfie | bool | Check for a selfie held up on another surface. |
naked | bool | Check for nudity. |
tattoo | bool | Check for tattoos. |
Headers:
| Header | Required | Description |
|---|---|---|
App-Id | No | The App-Id the transaction is scoped to; selects the per-app config for challenge settings and flash liveness. Defaults to default if omitted. |
Returns: CreateTransactionResponse
INFO
Unrecognized sanity_options keys are dropped silently rather than rejected. A typo means the check you intended simply never runs — verify against the allow-list above rather than assuming a misspelled key would error.
Sample Request
curl --location '<BASE_URL>/v1/create_transaction' \
-H 'Authorization: ATV <ACCESS_ID>:<SIGNATURE>' \
--header 'X-TV-Timestamp: <TIMESTAMP>' \
--header 'App-Id: <APP_ID>' \
--header 'Content-Type: application/json' \
--data '{
"user_id": "user_00000001",
"ref_id": "ref_00000001",
"level": 0,
"sanity_options": {
"mask_check": true,
"glasses_check": false
},
"enable_flash_liveness": false
}'Response
{
"success": true,
"code": 0,
"message": "Success",
"data": {
"request_id": "f48085e4-3ae4-40bb-b0e1-9b2c72575bc1",
"transaction": {
"id": "85712834-558f-4d9b-81bd-a2ab3b9a3aad",
"ref_id": "ref_00000001",
"user_id": "user_00000001",
"status": "NOT_VERIFIED",
"token": "<JWT_TOKEN>",
"level": 0
}
},
"errors": []
}| Field | Type | Description |
|---|---|---|
success | boolean | Whether the API call succeeded. |
code | integer | Response code — 0 on success. |
message | string | Response message. |
data.request_id | string | Request ID (UUID) for tracking. |
data.transaction.id | string | Transaction ID (UUID). |
data.transaction.ref_id | string | Reference ID provided in the request. |
data.transaction.user_id | string | User ID provided in the request. |
data.transaction.status | string | Transaction status, e.g. NOT_VERIFIED. |
data.transaction.token | string | JWT token for the transaction. |
data.transaction.level | integer | Challenge level for the transaction. |
errors[].code | string | Error code identifier. |
errors[].message | string | Error message. |
errors[].detail | object | Additional error details, which may include the field name. |
The HTTP status is 200 whenever the request is processed, successfully or not.
Note the transaction is nested under data.transaction here, unlike the eKYC and NFC create endpoints which return it flat under data.
Failure response
{
"success": false,
"code": 4001000,
"message": "Input parameter violates a constraint.",
"data": {
"request_id": "f48085e4-3ae4-40bb-b0e1-9b2c72575bc1"
},
"errors": [
{
"code": "invalid_parameter_exception",
"message": "Input parameter violates a constraint.",
"detail": {
"reason": "Invalid challenge level."
}
}
]
}Errors
| Code | Message |
|---|---|
2001010 | Access ID not found in the system. |
2001020 | Transaction lock failed. |
2001021 | Invalid transaction request. |
2002206 | User profile is locked. |
401100 | Unauthorized action. You do not have permission to perform this action. |
4001000 | Input parameter violates a constraint. |
4001001 | The X-TV-Timestamp header is expired. Please provide a newer timestamp. |
4041002 | The profile of user not found. |
5001000 | Some unexpected error occurs while processing the request. |
| Code | Description |
|---|---|
access_id_not_found | Access ID not found in the system. |
transaction_lock_failed | Transaction lock failed. |
transaction_invalid_request | Invalid transaction request. |
access_denied_exception | Unauthorized action. You do not have permission to perform this action. |
user_profile_not_found_exception | The profile of user not found. |
user_profile_locked | User profile is locked. |
invalid_parameter_exception | Input parameter violates a constraint. |
request_time_too_skewed | The X-TV-Timestamp header is expired. Please provide a newer timestamp. |
internal_server_error | Some unexpected error occurs while processing the request. |
A 4041002 means no profile exists yet — call Register Faces first. A 2002206 means the profile is locked; see Unlock Profile.
Next Steps
- Request Signing — how the SDK signs with the token returned here
- Verify Face Authen — the SDK's next call