Introduction
Welcome to the iDenFace developers' guide! This guide provides comprehensive information on integrating and utilizing our technology "iDenFace" for facial recognition and verification in your application. To get started, you'll need to request the license from us. To request the license, kindly email us at info@toppangravity.com. Once you receive the license key and complete the initial setup, you can begin using the services by following the provided guide.
We have language bindings in Python and Java! You can view code examples in the dark area to the right, and you can switch the programming language of the examples with the tabs in the top right.
If you need any info, feel free to write us at info@toppangravity.com.
Requirements of Image Acquistion
The uploaded selfie image must conform to the following conditions:
Use 720P (or above) resolution to capture face images.
Use JPG format with quality 100 and then encode to base64 string.
Face Size and Pose Requirements
Out-of-plane rotation (face pitch and yaw) angle: from -30±3 to 30±3 degrees.
Note that the accuracy of the Liveness Detection result is degraded in photos with a face roll angle greater than 45.
Minimal distance between the eyes (interpupillary distance) of the subject: 60-80 px (depends on the pipeline used) for mobile platforms and 150 px for desktop and webcam images. This parameter may be adjusted in the configuration file, however, it is not recommended to set it lower than the default value, because it will affect the accuracy.
For mobile platforms minimal face size is 192-224 pixels (depending on the pipeline used) in any dimension and the face should occupy at least 25% of the area in the image. For desktop and webcam photos minimal face size is 350 pixels and the face should occupy at least 15% of the area in the image.
Face Image Attribute Requirements
The maximum number of faces in an image is set to 1. Only allow one face within one image.
Face should be fully open without any occlusions.
Face should be fully visible within a frame and should have enough padding around it. The default minimum value is 3-25 pixels (depending on the pipeline used).
Face Image Quality Requirements
- Motion blur effect can significantly increase BPCER (“Bona Fide Presentation Classification Error Rate” or the rate of errors classifying a live person as a spoof).
- Fish-eye lenses are not supported by this API.
- Texture filtering can significantly increase APCER. (“Attack Presentation Classification Error Rate” or the errors of allowing impostors through), therefore remove texture filtering
- Spotlights on the faces and nearest surroundings can significantly increase BPCER.
- Ill-lighted environment and colored light can significantly increase BPCER.
Generate Token
import requests
import json
url = "https://idenfacedev.toppanidgate.com/api/controller/generate_token"
payload = json.dumps({
"enableFace11": True,
"enableFaceManager": True,
"enableImageManager": True,
"enableLiveness": True,
"subject": "test"
})
headers = {
'Content-Type': 'application/json'
}
response = requests.request("POST", url, headers=headers, data=payload)
print(response.text)
OkHttpClient client = new OkHttpClient().newBuilder()
.build();
MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "{\r\n\n \"enableFace11\": true,\r\n \"enableFaceManager\": true,\r\n \"enableImageManager\": true,\r\n \"enableLiveness\": true,\r\n \"subject\": \"test\"\r\n}");
Request request = new Request.Builder()
.url("https://idenfacedev.toppanidgate.com/api/controller/generate_token")
.method("POST", body)
.addHeader("Content-Type", "application/json")
.build();
Response response = client.newCall(request).execute();
The above snippet returns JSON structured like this:
{
"responseBody": {
"jwt": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJ0ZXN0IiwiZW5hYmxlRmFjZU1hbmFnZXIiOnRydWUsImlzcyI6IlRvcHBhbmlER2F0ZSIsImVuYWJsZUltYWdlTWFuYWdlciI6dHJ1ZSwiZXhwIjoxNjk1MjMzODI2LCJlbmFibGVMaXZlbmVzcyI6dHJ1ZSwiaWF0IjoxNjk1MTk3ODI2LCJlbmFibGVFbmNyeXB0b3IiOmZhbHNlLCJlbmFibGVGYWNlMTEiOnRydWUsImp0aSI6ImQ1NWYzMTFkLTkwNWUtNDk3MC04NmRkLTI0NzcxYjBlMWRkMSJ9.Vx4Wx3OB-iO-ghzu-7kkZIUQl6j2demDZNwRApV8JfqIFiHQa2J-YuzctsQY0WKWGqy1PLFaHCI_PP4zsOYqvhKW84-VqLBDqJ6etk3HLROhEv3zipOxeFL7suvt4Ro3nMW3DF4dQDjv8fIbfp-FCcRhsXbIhMQddromj5AvPlvRRcs8dRTQiR-j6xh56HMZEscpDT0puDnE1W2vErDlKANgCAruz7D_WG3zPzdegm6Mm5wzKtbAbSL9sq8ml-mVSNMlFqYBiN8i3T5-VvcCxtsKmUAtak7MhjBFiWV-oEPoLcC-XogwhozkBSMR-H0czMEbLGEuRlp0ZZSBDyNRKA"
},
"status": "OK"
}
Retrieve token to get authorization.
HTTP Request
POST https://idenfacedev.toppanidgate.com/api/controller/generate_token
Query Parameters
Parameter | Type | Description |
---|---|---|
enableEncryptor | Boolean | Enable to encrypt or not. |
enableFace11 | Boolean | Enable the face recognition or not. |
enableFaceManager | Boolean | Enable the face management or not. |
enableImageManager | Boolean | Enable the image management or not. |
enableLiveness | Boolean | Enable the liveness or not. |
subject | String | Noted the subject of the token. |
Retrieve Public Key
import requests
import json
url = "https://idenfacedev.toppanidgate.com/api/controller/retrieve_pubky"
payload = json.dumps({})
headers = {
'Content-Type': 'application/json',
'Authorization': 'Bearer {{jwt}}'
}
response = requests.request("POST", url, headers=headers, data=payload)
print(response.text)
OkHttpClient client = new OkHttpClient().newBuilder()
.build();
MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "{}");
Request request = new Request.Builder()
.url("https://idenfacedev.toppanidgate.com/api/controller/retrieve_pubky")
.method("POST", body)
.addHeader("Content-Type", "application/json")
.addHeader("Authorization", "Bearer {{jwt}}")
.build();
Response response = client.newCall(request).execute();
The above snippet returns JSON structured like this:
{
"responseBody": {
"key": "30820122300D06092A864886F70D01010105000382010F003082010A0282010100B5F4B827FB91D6D10E4A69FB6BF70F5CCBEDFD0920937F1F8DBC460278A4794E879EB139DCE6670F2AB4E25A0F6F020954252C69B3C3F54B3BACC715074C1CF77FCA6564689D319A98394749B1FC42EC6F88A8C6D1C265E16D6BB2DC01B6A12BB8E604250FE617527E4E4BFEC7A7ACE6EA18F1C54FDF3C1581BF44911045BB31ADCABAA6634C27A0C74ADBC8CDC66C1B8DDB376CAF9D6BFDFBFFFBB699C3EC72173900CC9E12DE9E4CE34560746C7E934648DAEA8627B0D4AB40B6075A810455521E7FA4F1DF0E8A9F1FA7FD94EC5B3DF76E806354FEC1E153F5CCDD6C472E312DAEDB862D9E4E76A7914C1EF6712CADB9FD12E45A5C20BCFC24931C72E4F8530203010001"
},
"status": "OK"
}
Retrieve public key for end-to-end encryption.
HTTP Request
POST https://idenfacedev.toppanidgate.com/api/controller/retrieve_pubky
Query Parameters
Parameter | Type | Description |
---|
Enrollment - Card:Selfie Comparison
import requests
import json
url = "https://idenfacedev.toppanidgate.com/api/controller/self_card_enroll"
payload = json.dumps({
"user_id": "",
"channel_id": "cube",
"user_name": "",
"parameter": {
"angle_calibration": True,
"occlusion": True,
"face_angle_difference": 15,
"face_left_angle_range": [
35,
58
],
"face_right_angle_range": [
35,
57
]
},
"image_info": "base64UrlEncodeString",
"category": "VISA",
"type": "XXX",
"meta": {
"os": "IOS",
"manufacturer": "SAMSUNG",
"model": "UNKNOWN",
"cropped": 0
}
})
headers = {
'Content-Type': 'application/json',
'Authorization': 'Bearer {{jwt}}'
}
response = requests.request("POST", url, headers=headers, data=payload)
print(response.text)
OkHttpClient client = new OkHttpClient().newBuilder()
.build();
MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "{\r\n \n \n \"user_id\": \"\",\r\n \"channel_id\": \"cube\",\r\n \"user_name\": \"\",\r\n \"parameter\": {\r\n \"angle_calibration\": true,\r\n \"occlusion\": true,\r\n \"face_angle_difference\": 15,\r\n \"face_left_angle_range\": [\r\n 35.0,\r\n 58.0\r\n ],\r\n \"face_right_angle_range\": [\r\n 35.0,\r\n 57.0\r\n ]\r\n },\r\n \"image_info\":\"base64UrlEncodeString\",\r\n \"category\": \"VISA\",\r\n \"type\": \"XXX\",\r\n \"meta\": {\r\n \"os\": \"IOS\",\r\n \"manufacturer\": \"SAMSUNG\",\r\n \"model\": \"UNKNOWN\",\r\n \"cropped\": 0\r\n }\r\n}");
Request request = new Request.Builder()
.url("https://idenfacedev.toppanidgate.com/api/controller/self_card_enroll")
.method("POST", body)
.addHeader("Content-Type", "application/json")
.addHeader("Authorization", "Bearer {{jwt}}")
.build();
Response response = client.newCall(request).execute();
The above snippet returns JSON structured like this:
{
"transaction_id": "01bb413e-38cf-41f1-ac07-d72548bea2b3",
"transaction_status": 2,
"responseBody": {
"feature_extract_response": {
"result": {
"pipeline": "advance-v1.1.1",
"face_side_angles": [
40.504993,
47.603737,
7.0987434
],
"adapter": "IDGateFace11-v1.13.0",
"face_bbox": [
145,
344,
564,
975
],
"face_vector": "base64UrlEncodeString"
},
"reason": null,
"message": "Success to extract feature from the uploaded image.",
"status": "F11_0000"
},
"face_id": 63,
"pk": 0,
"message": "Operation successful.",
"face_feature_id": 124,
"image_id": 159,
"status": "IDFCTR_0000"
},
"channel_id": "TP_IDGATE",
"status": "OK"
}
Request a card with photo to enroll.
HTTP Request
POST https://idenfacedev.toppanidgate.com/api/controller/self_card_enroll
Query Parameters
Parameter | Type | Description |
---|---|---|
user_id | String | User ID(UUID) which provided by APP backend. |
channel_id | String | The client ID represents the client that current user is belong to, ex. TP_IDGATE. |
user_name | String | Username which provided by APP backend. |
parameter | JSON Object | |
angle_calibration | Boolean | The flag to turn on/off the automatic angle calibration. (True|False) |
occlusion | Boolean | The flag to turn on/off the occlusion check. (True|False) |
face_angle_difference | Float | (The acceptable value of the difference between face angles. (Suggest 15) |
face_left_angle_range | List | The acceptable range of the face left sideangle: [minimum, maximum]. (Suggest [35.0, 58.0]) |
face_right_angle_range | List | The acceptable range of the face right side angle: [minimum, maximum]. (Suggest[35.0, 58.0]) |
image_info | String(1.5MB) | Images (whole ID Card image, passport image, etc.) encoded with base64 url-encode. |
category | String Category of the uploaded images: (VISA) | |
type | String | The subclass of the uploaded image. |
meta | JSON Object | The metadata of the uploaded image. |
os | String | The OS of the image capture. (IOS|ANDROID|WINDOWS). |
manufacturer | String | The manufacturer of the image capture. |
model | String | The model of the image capture. |
cropped | Int | This parameter shows the uploaded images are cropped photo(cropped=1) or full ID image(cropped=0) |
Verification - Card:Selfie Comparison
import requests
import json
url = "https://idenfacedev.toppanidgate.com/api/controller/self_card_verify"
payload = json.dumps({
"transaction_id": "",
"user_id": "",
"channel_id": "cube",
"user_name": "",
"parameter": {
"angle_calibration": True,
"occlusion": True,
"face_angle_difference": 15,
"face_left_angle_range": [
35,
58
],
"face_right_angle_range": [
35,
57
],
"liveness": True,
"liveness_threshold": 0.5,
"similarity_threshold": 0.75
},
"image_info": "",
"category": "SELFIE",
"type": "JP_DRIVE",
"meta": {
"os": "IOS",
"manufacturer": "SAMSUNG",
"model": "UNKNOWN",
"cropped": 0
}
})
headers = {
'Content-Type': 'application/json',
'Authorization': 'Bearer {{jwt}}'
}
response = requests.request("POST", url, headers=headers, data=payload)
print(response.text)
OkHttpClient client = new OkHttpClient().newBuilder()
.build();
MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "{\r\n \n \"transaction_id\": \"\",\r\n \"user_id\": \"\",\r\n \"channel_id\": \"cube\",\r\n \"user_name\": \"\",\r\n \"parameter\": {\r\n \"angle_calibration\": true,\r\n \"occlusion\": true,\r\n \"face_angle_difference\": 15,\r\n \"face_left_angle_range\": [\r\n 35.0,\r\n 58.0\r\n ],\r\n \"face_right_angle_range\": [\r\n 35.0,\r\n 57.0\r\n ],\r\n \"liveness\": true,\r\n \"liveness_threshold\": 0.5,\r\n \n \n \"similarity_threshold\": 0.75\r\n },\r\n \"image_info\": \"\",\r\n \"category\": \"SELFIE\",\r\n \"type\": \"JP_DRIVE\",\r\n \"meta\": {\r\n \"os\": \"IOS\",\r\n \"manufacturer\": \"SAMSUNG\",\r\n \"model\": \"UNKNOWN\",\r\n \"cropped\": 0\r\n \n }\r\n}");
Request request = new Request.Builder()
.url("https://idenfacedev.toppanidgate.com/api/controller/self_card_verify")
.method("POST", body)
.addHeader("Content-Type", "application/json")
.addHeader("Authorization", "Bearer {{jwt}}")
.build();
Response response = client.newCall(request).execute();
The above snippet returns JSON structured like this:
{
"transaction_id": "3c77fa73-b726-4ce7-9ca1-56a5116bfe21",
"transaction_status": 2,
"responseBody": {
"face_liveness_response": {
"result": {
"score": 12.057634,
"probability": 0.99999416,
"error_code": null,
"error": null,
"quality": 0.82199633
},
"reason": null,
"message": "Operation Success.",
"status": "LIV_0000"
},
"face_verify_response": {
"result": {
"pipeline": "advance-v1.1.1",
"face_side_angles": [
50.348442,
45.37481,
4.973633
],
"normalized_score": 1,
"adapter": "IDGateFace11-v1.13.0",
"original_score": 1,
"face_bbox": [
98,
119,
361,
492
],
"face_vector": "base64UrlEncodeString"
},
"reason": null,
"message": "Success to perform verification.",
"status": "F11_0000"
},
"face_id": 64,
"pk": 0,
"message": "Operation successful.",
"face_feature_id": 127,
"image_id": 164,
"status": "IDFCTR_0000"
},
"channel_id": "TP_IDGATE",
"status": "OK"
}
Request the selfie to verify with the card photo.
HTTP Request
POST https://idenfacedev.toppanidgate.com/api/controller/self_card_verify
Query Parameters
Parameter | Type | Description |
---|---|---|
transaction_id | String | The transaction id that provided by the APP backend. |
user_id | String | User ID which provided by APP backend. |
channel_id | String | The client ID represents the client that current user is belong to, ex. TP_IDGATE. |
user_name | String | Username which provided by APP backend. |
parameter | JSON Object | |
angle_calibration | Boolean | The flag to turn on/off the automatic angle calibration. (True|False) |
occlusion | Boolean | The flag to turn on/off the occlusion check. (True|False) |
face_angle_difference | Float | (The acceptable value of the difference between face angles. (Suggest 15) |
face_left_angle_range | List | The acceptable range of the face left sideangle: [minimum, maximum]. (Suggest [35.0, 58.0]) |
face_right_angle_range | List | The acceptable range of the face right side angle: [minimum, maximum]. (Suggest[35.0, 58.0]) |
liveness | Boolean | Detect the liveness or not. |
liveness_threshold | Float | The threadhold of the liveness probability. (Suggest 0.5) |
similarity_threshold | Float | The threadhold of the normalized score.(Suggest 0.7) |
image_info | String(1.5MB) | Selfie images encoded with base64 url-encode. |
category | String | Category of the uploaded images: (SLEFIE) |
type | String | The subclass of the uploaded image. |
meta | JSON | ObjectThe metadata of the uploaded image. |
os | String | The OS of the image capture. (IOS|ANDROID|WINDOWS). |
manufacturer | String | The manufacturer of the image capture. |
model | String | The model of the image capture. |
cropped | Int | This parameter shows the uploaded images are cropped photo(cropped=1) or full ID image(cropped=0) |
Enrollment - 1:1 Comparison
import requests
import json
url = "https://idenfacedev.toppanidgate.com/api/controller/self_self_enroll"
payload = json.dumps({
// "transaction_id": "{{txn_id}}",
"user_id": "{{curr_uuid}}",
"channel_id": "counter",
"user_name": "{{user_name}}",
"parameter": {
"angle_calibration": true,
"occlusion": true,
"face_angle_difference": 15,
"face_left_angle_range": [
35.0,
58.0
],
"face_right_angle_range": [
35.0,
57.0
],
"liveness":true,
"liveness_threshold": 1.9,
// "liveness_calibration": "SOFT",
// "liveness_pipeline": "dionysus"
},
"image_info": "",
"category": "SELFIE",
"type": "JP_DRIVE",
"meta": {
"os": "IOS",
"manufacturer": "SAMSUNG",
"model": "UNKNOWN",
"cropped": 0
}
})
headers = {
'Content-Type': 'application/json',
'Authorization': 'Bearer {{jwt}}'
}
response = requests.request("POST", url, headers=headers, data=payload)
print(response.text)
OkHttpClient client = new OkHttpClient().newBuilder()
.build();
MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "{\r\n \n \"user_id\": \"\",\r\n \"channel_id\": \"counter\",\r\n \"user_name\": \"\",\r\n \"parameter\": {\r\n \"angle_calibration\": true,\r\n \"occlusion\": true,\r\n \"face_angle_difference\": 15,\r\n \"face_left_angle_range\": [\r\n 35.0,\r\n 58.0\r\n ],\r\n \"face_right_angle_range\": [\r\n 35.0,\r\n 57.0\r\n ],\r\n \"liveness\":true,\r\n \"liveness_threshold\": 1.9,\r\n \n \n },\r\n \"image_info\": \"\",\r\n \"category\": \"SELFIE\",\r\n \"type\": \"JP_DRIVE\",\r\n \"meta\": {\r\n \"os\": \"IOS\",\r\n \"manufacturer\": \"SAMSUNG\",\r\n \"model\": \"UNKNOWN\",\r\n \"cropped\": 0\r\n }\r\n}");
Request request = new Request.Builder()
.url("https://idenfacedev.toppanidgate.com/api/controller/self_self_enroll")
.method("POST", body)
.addHeader("Content-Type", "application/json")
.addHeader("Authorization", "Bearer {{jwt}}")
.build();
Response response = client.newCall(request).execute();
The above snippet returns JSON structured like this:
{
"transaction_id": "a2158360-1074-4381-89a1-3041728e703c",
"transaction_status": 2,
"channel_id": "counter",
"responseBody": {
"status": "IDFCTR_0000",
"message": "Operation successful.",
"face_id": 506,
"face_feature_id": 3065,
"image_id": 4220,
"pk": 0,
"face_liveness_response": {
"reason": null,
"status": "LIV_0000",
"message": "Operation Success.",
"result": {
"error": null,
"error_code": null,
"score": 19.802925,
"quality": 0.94497615,
"probability": 1
}
},
"face_extract_response": {
"reason": null,
"status": "F11_0000",
"message": "Success to extract feature from the uploaded image.",
"result": {
"adapter": "IDGateFace11-v1.13.0",
"pipeline": "advance-v1.1.1",
"face_vector": " base64UrlEncodeString ",
"face_bbox": [
145,
344,
564,
975
],
"face_side_angles": [
40.505722,
47.605087,
7.099365
]
}
}
},
"status": "OK"
}
Request a card with photo to enroll.
HTTP Request
POST https://idenfacedev.toppanidgate.com/api/controller/self_self_enroll
Query Parameters
Parameter | Type | Description |
---|---|---|
user_id | String | User ID(UUID) which provided by APP backend. |
channel_id | String | The client ID represents the client that current user is belong to, ex. TP_IDGATE. |
user_name | String | Username which provided by APP backend. |
parameter | JSON Object | |
angle_calibration | Boolean | The flag to turn on/off the automatic angle calibration. (True|False) |
occlusion | Boolean | The flag to turn on/off the occlusion check. (True|False) |
face_angle_difference | Float | (The acceptable value of the difference between face angles. (Suggest 15) |
face_left_angle_range | List | The acceptable range of the face left sideangle: [minimum, maximum]. (Suggest [35.0, 58.0]) |
face_right_angle_range | List | The acceptable range of the face right side angle: [minimum, maximum]. (Suggest[35.0, 58.0]) |
liveness | Boolean | Detect the liveness or not. |
liveness_threshold | Float | The threadhold of the liveness probability. (Suggest 0.5) |
similarity_threshold | Float | The threadhold of the normalized score. (Suggest 0.7) |
image_info | String(1.5MB) | Images (whole ID Card image, passport image, etc.) encoded with base64 url-encode. |
category | String Category of the uploaded images: (VISA) | |
type | String | The subclass of the uploaded image. |
meta | JSON Object | The metadata of the uploaded image. |
os | String | The OS of the image capture. (IOS|ANDROID|WINDOWS). |
manufacturer | String | The manufacturer of the image capture. |
model | String | The model of the image capture. |
cropped | Int | This parameter shows the uploaded images are cropped photo(cropped=1) or full ID image(cropped=0) |
Verification - 1:1 Comparison
import requests
import json
url = "https://idenfacedev.toppanidgate.com/api/controller/self_self_verify"
payload = json.dumps({
"user_id": "",
"channel_id": "counter",
"user_name": "",
"parameter": {
"angle_calibration": True,
"occlusion": True,
"face_angle_difference": 15,
"face_left_angle_range": [
35,
58
],
"face_right_angle_range": [
35,
57
],
"liveness": True,
"liveness_threshold": 0.9,
"liveness_calibration": "SOFT",
"liveness_pipeline": "aphrodite",
"similarity_threshold": 1
},
"image_info": "",
"category": "SELFIE",
"type": "JP_DRIVE",
"meta": {
"os": "IOS",
"manufacturer": "SAMSUNG",
"model": "UNKNOWN",
"cropped": 0
}
})
headers = {
'Content-Type': 'application/json',
'Authorization': 'Bearer {{jwt}}'
}
response = requests.request("POST", url, headers=headers, data=payload)
print(response.text)
OkHttpClient client = new OkHttpClient().newBuilder()
.build();
MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "{\r\n \n \n \"user_id\": \"\",\r\n \"channel_id\": \"counter\",\r\n \"user_name\": \"\",\r\n \"parameter\": {\r\n \"angle_calibration\": true,\r\n \"occlusion\": true,\r\n \"face_angle_difference\": 15,\r\n \"face_left_angle_range\": [\r\n 35.0,\r\n 58.0\r\n ],\r\n \"face_right_angle_range\": [\r\n 35.0,\r\n 57.0\r\n ],\r\n \"liveness\": true,\r\n \"liveness_threshold\": 0.9,\r\n \"liveness_calibration\": \"SOFT\",\r\n \"liveness_pipeline\": \"aphrodite\",\r\n \"similarity_threshold\": 1\r\n },\r\n \"image_info\": \"\",\r\n \"category\": \"SELFIE\",\r\n \"type\": \"JP_DRIVE\",\r\n \"meta\": {\r\n \"os\": \"IOS\",\r\n \"manufacturer\": \"SAMSUNG\",\r\n \"model\": \"UNKNOWN\",\r\n \"cropped\": 0\r\n }\r\n}");
Request request = new Request.Builder()
.url("https://idenfacedev.toppanidgate.com/api/controller/self_self_verify")
.method("POST", body)
.addHeader("Content-Type", "application/json")
.addHeader("Authorization", "Bearer {{jwt}}")
.build();
Response response = client.newCall(request).execute();
The above snippet returns JSON structured like this:
{
"transaction_id": "cef65cdd-f826-4567-abeb-4044f2a26c8a",
"transaction_status": 2,
"channel_id": "counter",
"responseBody": {
"status": "IDFCTR_0000",
"message": "Operation successful.",
"face_id": 506,
"face_feature_id": 3066,
"image_id": 4221,
"pk": 0,
"face_liveness_response": {
"reason": null,
"status": "LIV_0000",
"message": "Operation Success.",
"result": {
"error": null,
"error_code": null,
"score": 19.802925,
"quality": 0.94497615,
"probability": 1
}
},
"face_verify_response": {
"reason": null,
"status": "F11_0000",
"message": "Success to perform verification.",
"result": {
"adapter": "IDGateFace11-v1.13.0",
"pipeline": "advance-v1.1.1",
"face_vector": "base64UrlEncodeString",
"face_bbox": [
145,
344,
564,
975
],
"face_side_angles": [
40.505722,
47.605087,
7.099365
],
"original_score": 1,
"normalized_score": 1
}
}
},
"status": "OK"
}
Request the selfie to verify with the card photo.
HTTP Request
POST https://idenfacedev.toppanidgate.com/api/controller/self_self_verify
Query Parameters
Parameter | Type | Description |
---|---|---|
transaction_id | String | The transaction id that provided by the APP backend. |
user_id | String | User ID which provided by APP backend. |
channel_id | String | The client ID represents the client that current user is belong to, ex. TP_IDGATE. |
user_name | String U | sername which provided by APP backend. |
parameter | JSON Object | |
angle_calibration | Boolean | The flag to turn on/off the automatic angle calibration. (True|False) |
occlusion | Boolean | The flag to turn on/off the occlusion check. (True|False) |
face_angle_difference | Float | (The acceptable value of the difference between face angles. (Suggest 15) |
face_left_angle_range | List | The acceptable range of the face left sideangle: [minimum, maximum]. (Suggest [35.0, 58.0]) |
face_right_angle_range | List | The acceptable range of the face right side angle: [minimum, maximum]. (Suggest[35.0, 58.0]) |
liveness | Boolean | Detect the liveness or not. |
liveness_threshold | Float | The threadhold of the liveness probability. (Suggest 0.5) |
liveness_calibration | String | APCER / BPCER balance: REGULAR: (the default) targets low APCER. SOFT: achieves lower BPCER while still having acceptable APCER. HARDENED: targets extra low APCER with higher BPCER. |
liveness_pipeline | String | The name and version of the pipeline which provided the current results. |
similarity_threshold | Float | The threadhold of the normalized score.(Suggest 0.7) |
image_info | String(1.5MB) | Selfie images encoded with base64 url-encode. |
category | String | Category of the uploaded images: (SLEFIE) |
type | String | The subclass of the uploaded image. |
meta | JSON | ObjectThe metadata of the uploaded image. |
os | String | The OS of the image capture. (IOS|ANDROID|WINDOWS). |
manufacturer | String | The manufacturer of the image capture. |
model | String | The model of the image capture. |
cropped | Int | This parameter shows the uploaded images are cropped photo(cropped=1) or full ID image(cropped=0) |
Find Image By ID
import requests
import json
url = "https://idenfacedev.toppanidgate.com/api/controller/find_image"
payload = json.dumps({
"channel_id": "TP_IDGATE",
"image_id": 159,
"shrunk_image": true
})
headers = {
'Content-Type': 'application/json',
'Authorization': 'Bearer {{jwt}}'
}
response = requests.request("POST", url, headers=headers, data=payload)
print(response.text)
OkHttpClient client = new OkHttpClient().newBuilder()
.build();
MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "{\r\n \"channel_id\": \"TP_IDGATE\",\r\n \"image_id\": 159,\r\n \"shrunk_image\": true\r\n}");
Request request = new Request.Builder()
.url("https://idenfacedev.toppanidgate.com/api/controller/find_image")
.method("POST", body)
.addHeader("Content-Type", "application/json")
.addHeader("Authorization", "Bearer {{jwt}}")
.build();
Response response = client.newCall(request).execute();
The above snippet returns JSON structured like this:
{
"status": "OK",
"responseBody": {
"image_info": "base64UrlEncodeString",
"face_id": 64,
"message": "Operation successful.",
"face_feature_id": 125,
"status": "IDFCTR_0000"
}
}
Get the images by specified image_id.
HTTP Request
POST https://idenfacedev.toppanidgate.com/api/controller/find_image
Query Parameters
Parameter | Type | Description |
---|---|---|
channel_id | String | The client ID represents the client that current user is belong to, ex. TP_IDGATE. |
image_id | Int | The image id that provided by the Controller. |
shrunk_image | Boolean | Retrieve the shrunk image(True) or original image(False). |
Valdiate Photo for Enrollment
import requests
import json
url = "https://idenfacedev.toppanidgate.com/api/controller/find_image"
payload = json.dumps({
"parameter": {
"angle_calibration": true,
"occlusion": true,
"face_angle_difference": 15,
"face_left_angle_range": [
35.0,
58.0
],
"face_right_angle_range": [
35.0,
57.0
],
"liveness":true,
"liveness_threshold": 0.5,
},
"image_info": "base64UrlEncodeString",
}
})
headers = {
'Content-Type': 'application/json',
'Authorization': 'Bearer {{jwt}}'
}
response = requests.request("POST", url, headers=headers, data=payload)
print(response.text)
OkHttpClient client = new OkHttpClient().newBuilder()
.build();
MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "{\r\n \"parameter\": {\r\n \"angle_calibration\": true,\r\n \"occlusion\": true,\r\n \"face_angle_difference\": 15,\r\n \"face_left_angle_range\": [\r\n 35.0,\r\n 58.0\r\n ],\r\n \"face_right_angle_range\": [\r\n 35.0,\r\n 57.0\r\n ],\r\n \"liveness\":true,\r\n \"liveness_threshold\": 0.5,\r\n },\r\n \"image_info\": \"base64UrlEncodeString\",\r\n }\r\n}");
Request request = new Request.Builder()
.url("https://idenfacedev.toppanidgate.com/api/controller/find_image")
.method("POST", body)
.addHeader("Content-Type", "application/json")
.addHeader("Authorization", "Bearer {{jwt}}")
.build();
Response response = client.newCall(request).execute();
The above snippet returns JSON structured like this:
{
"transaction_id": "a2158360-1074-4381-89a1-3041728e703c",
"transaction_status": 2,
"responseBody": {
"status": "IDFCTR_0000",
"message": "Operation successful.",
"face_liveness_response": {
"reason": null,
"status": "LIV_0000",
"message": "Operation Success.",
"result": {
"error": null,
"error_code": null,
"score": 19.802925,
"quality": 0.94497615,
"probability": 1
}
},
"face_extract_response": {
"reason": null,
"status": "F11_0000",
"message": "Success to extract feature from the uploaded image.",
"result": {
"adapter": "IDGateFace11-v1.13.0",
"pipeline": "advance-v1.1.1",
"face_bbox": [
145,
344,
564,
975
],
"face_side_angles": [
40.505722,
47.605087,
7.099365
]
}
}
},
"status": "OK"
}
Validate the photo if it can be enrolled or not.
HTTP Request
POST https://idenfacedev.toppanidgate.com/api/controller/photo_detect
Query Parameters
Parameter | Type | Description |
---|---|---|
parameter | JSON Object | |
angle_calibration | Boolean | The flag to turn on/off the automatic angle calibration. (True|False) |
occlusion | Boolean | The flag to turn on/off the occlusion check. (True|False) |
face_angle_difference | Float | (The acceptable value of the difference between face angles. (Suggest 15) |
face_left_angle_range | List | The acceptable range of the face left side angle: [minimum, maximum]. (Suggest [35.0, 58.0]) |
face_right_angle_range | List | The acceptable range of the face right side angle: [minimum, maximum]. (Suggest [35.0, 58.0]) |
liveness | Boolean | Detect the liveness or not. Client specify |
liveness_threshold | Float | The threadhold of the liveness probability. (Suggest 0.5) |
image_info | String(1.5MB) | Images (whole ID Card image, passport image, etc.) encoded with base64 url-encode. |
Compare Two Photos
import requests
import json
url = "https://idenfacedev.toppanidgate.com/api/controller/find_image"
payload = json.dumps({
"transaction_id": "444922cf-0a83-471c-9717-43c8d122e111",
"user_id": "donny1126",
"channel_id": "test_channel_id",
"parameter": {
"angle_calibration": true,
"occlusion": true,
"face_angle_difference": 15,
"face_left_angle_range": [
35.0,
58.0
],
"face_right_angle_range": [
35.0,
57.0
],
"use_urlsafe_base64": false,
"similarity_threshold": 0.5
},
"image_info1": {
"data": ["A_STRING_THAT_ECODED_WITH_BASE64_IMAGE"],
"category": "VISA",
"type": "JP_DRIVE",
"meta": {
"os": "IOS",
"manufacturer": "SAMSUNG",
"model": "UNKNOWN",
"cropped": 0
}
},
"image_info2": {
"data": ["A_STRING_THAT_ECODED_WITH_BASE64_IMAGE"],
"category": "VISA",
"type": "JP_DRIVE",
"meta": {
"os": "IOS",
"manufacturer": "SAMSUNG",
"model": "UNKNOWN",
"cropped": 0
}
}
}
)
headers = {
'Content-Type': 'application/json',
'Authorization': 'Bearer {{jwt}}'
}
response = requests.request("POST", url, headers=headers, data=payload)
print(response.text)
OkHttpClient client = new OkHttpClient().newBuilder()
.build();
MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "{\r\n \"transaction_id\": \"444922cf-0a83-471c-9717-43c8d122e111\",\r\n \"user_id\": \"donny1126\",\r\n \"channel_id\": \"test_channel_id\",\r\n \"parameter\": {\r\n \"angle_calibration\": true,\r\n \"occlusion\": true,\r\n \"face_angle_difference\": 15,\r\n \"face_left_angle_range\": [\r\n 35.0,\r\n 58.0\r\n ],\r\n \"face_right_angle_range\": [\r\n 35.0,\r\n 57.0\r\n ],\r\n \"use_urlsafe_base64\": false,\r\n \"similarity_threshold\": 0.5\r\n },\r\n \"image_info1\": {\r\n \"data\": [\"A_STRING_THAT_ECODED_WITH_BASE64_IMAGE\"],\r\n \"category\": \"VISA\",\r\n \"type\": \"JP_DRIVE\",\r\n \"meta\": {\r\n \"os\": \"IOS\",\r\n \"manufacturer\": \"SAMSUNG\",\r\n \"model\": \"UNKNOWN\",\r\n \"cropped\": 0\r\n }\r\n },\r\n \"image_info2\": {\r\n \"data\": [\"A_STRING_THAT_ECODED_WITH_BASE64_IMAGE\"],\r\n \"category\": \"VISA\",\r\n \"type\": \"JP_DRIVE\",\r\n \"meta\": {\r\n \"os\": \"IOS\",\r\n \"manufacturer\": \"SAMSUNG\",\r\n \"model\": \"UNKNOWN\",\r\n \"cropped\": 0\r\n }\r\n }\r\n }");
Request request = new Request.Builder()
.url("https://idenfacedev.toppanidgate.com/api/controller/find_image")
.method("POST", body)
.addHeader("Content-Type", "application/json")
.addHeader("Authorization", "Bearer {{jwt}}")
.build();
Response response = client.newCall(request).execute();
The above snippet returns JSON structured like this:
{
"transaction_id": "444922cf-0a83-471c-9717-43c8d122e111",
"transaction_status": 2,
"channel_id": "counter",
"responseBody": {
"status": "IDFCTR_0000",
"message": "Operation successful.",
"transaction_id": null,
"session_id": null,
"face_compare_response": {
"reason": null,
"status": "F11_0000",
"message": "Success to compare two uploaded faces.",
"result": {
"original_score": 0.88317657,
"normalized_score": 0.9910126,
"face_1_bbox": [
133,
177,
315,
423
],
"face_1_side_angles": [
51,
51,
0
],
"face_2_bbox": [
178,
97,
300,
264
],
"face_2_side_angles": [
57,
46,
11
],
"adapter": "IDGateFace11-v1.13.0",
"pipeline": "advance-v1.1.1"
}
}
},
"status": "OK"
}
To calculate the similarity score of two uploaded face images.
HTTP Request
POST https://idenfacedev.toppanidgate.com/api/controller/find_image
Query Parameters
Parameter | Type | Description |
---|---|---|
transaction_id | String The transaction id that provided by the APP backend. | |
channel_id | String The client ID represents the client that current user is belong to, ex. TP_IDGATE. | |
parameter | JSON Object | |
angle_calibration | Boolean The flag to turn on/off the automatic angle calibration. (True|False) | |
occlusion | Boolean The flag to turn on/off the occlusion check. (True|False) | |
face_angle_difference | Float (The acceptable value of the difference between face angles. (Suggest 15) | |
face_left_angle_range L | ist The acceptable range of the face left side angle: [minimum, maximum]. (Suggest [35.0, 58.0]) | |
face_right_angle_range | List The acceptable range of the face right side angle: [minimum, maximum]. (Suggest[35.0, 58.0]) | |
similarity_threshold | Float The threadhold of the normalized score.(Suggest 0.7) | |
image_info_1 | String (1.5MB) | Images (selfie, whole ID Card image, passport image, etc.) encoded with base64 url-encode. |
category_1 | String | Category of the uploaded images: (SLEFIE) |
type_1 | String | The subclass of the uploaded image. Client specify |
meta_1 | JSON | Object The metadata of the uploaded image. |
os | String | The OS of the image capture. (IOS |
manufacturer | String | The manufacturer of the image capture. |
model | String | The model of the image capture. |
cropped | Int | This parameter shows the uploaded images are cropped photo(cropped=1) or full ID image(cropped=0) |
image_info_2 | String(1.5MB) | Images (selfie, whole ID Card image, passport image, etc.) encoded with base64 url-encode. |
category_2 | String | Category of the uploaded images: (SLEFIE) |
type_2 | String | The subclass of the uploaded image. |
meta_2 | JSON Object | The metadata of the uploaded image. |
os | String | The OS of the image capture. (IOS |
manufacturer | String | The manufacturer of the image capture. |
model | String | The model of the image capture. |
cropped | Int | This parameter shows the uploaded images are cropped photo(cropped=1) or full ID image(cropped=0) |
Errors
Face 1:1 Error Code
The Face 1:1 service uses the following error codes:
Name | HTTP | Code / Status | Log Level | Message |
---|---|---|---|---|
INTERNAL_SERVER_ERROR | 500 | F11_0001 | CRITICAL | Internal server error. |
VALID_DURATION_NOT_ACHIEVE | 403 | F11_0100 | CRITICAL | Please use this service after the valid date is achieved. |
VALID_DURATION_OUT | 200 | F11_0101 | WARNING | The current authentication is out of date. Please request a new certification file. |
CERTIFICATION_EXPIRED | 403 | F11_0102 | CRITICAL | The current certification is expired. Please request a new certification file. |
CERTIFICATION_INVALID | 403 | F11_0103 | CRITICAL | The current certification is invalid. Please request a valid certification file. |
READ_IMAGE_FAILED | 200 | F11_0200 | ERROR | Failed to read the uploaded image. |
READ_VECTOR_FAILED | 200 | F11_0201 | ERROR | Failed to read the uploaded feature vector. |
VECTORS_LENGTH_INCONSISTENT | 200 | F11_0202 | ERROR | The lengths of the two upload vectors are different. |
VECTOR_LENGTH_INVALID | 200 | F11_0203 ERROR | The length of the upload vector is wrong. | |
INPUT_VALIDATE_FAILED | 422 | F11_0204 | ERROR | Failed to validate the body of the current request. |
BASE64_DECODE_FAILED | 200 | F11_0205 | ERROR | Failed to decode the base64 encoded string. |
FACE_DETECT_FAILED | 200 | F11_0300 | ERROR | Failed to detect face from the uploaded image. |
FACE_ANGLE_INVALID | 200 | F11_0301 | ERROR | The angle of the detected face is invalid. |
LANDMARK_POSITION_INVALID | 200 | F11_0302 | ERROR | The position of the detected landmark is invalid. |
FACE_ROLL_INVALID | 200 | F11_0303 | ERROR | The roll of the detected face is invalid. |
MULTIPLE_FACES_DETECTED | 200 | F11_0304 | ERROR | Multiple faces are detected. |
ANGLE_DETECT_FAILED | 200 | F11_0305 | ERROR | Failed to detect the correct face angle from the uploaded image. |
FACE_IS_OCCLUDED | 200 | F11_0306 | ERROR | The detected face is occluded. |
FACE_LEFT_ANGLE_INVALID | 200 | F11_0307 | ERROR | The face left angle of the uploaded image is invalid. |
FACE_RIGHT_ANGLE_INVALID | 200 | F11_0308 | ERROR | The face right angle of the uploaded image is invalid. |
FACE_ANGLE_DIFFERENCE_INVALID | 200 | F11_0309 | ERROR | The face angle difference of the uploaded image is invalid. |
ANGLE_DETECT_FAILED_OR_ FACE_IS_OCCLUDED |
200 | F11_0310 | ERROR | Failed to detect correct face angle or the detected face is occluded. |
FEATURE_EXTRACT_FAILED | 200 | F11_0400 | ERROR | Failed to extract feature from the uploaded image. |
Liveness Error Code
The Face 1:1 service uses the following error codes:
Name | HTTP | Code / Status | Log Level | Message |
---|---|---|---|---|
SUCCESS | 200 | LIV_0000 | INFO | null |
INTERNAL_SERVER_ERROR | 500 | LIV_0001 | CRITICAL | Internal Server Error |
VALID_DURATION_NOT_ACHIEVE | 403 | LIV_0100 | CRITICAL | Please use this service after reaching the validation date. |
VALID_DURATION_OUT | 200 | LIV_0101 | WARN | The current validation has expired; please request a new validation file. |
CERTIFICATION_EXPIRED | 403 | LIV_0102 | CRITICAL | The current certification has expired; please request a new certification file. |
CERTIFICATION_INVALID | 403 | LIV_0103 | CRITICAL | The current certification is invalid; please request a valid certification file. |
READ_IMAGE_FAILED | 400 | LIV_0200 | ERROR | Unable to read the uploaded image. |
READ_VECTOR_FAILED | 400 | LIV_0201 | ERROR | Unable to read the uploaded feature vector. |
VECTORS_LENGTH_INCONSISTENT | 400 | LIV_0202 | ERROR | The lengths of the two uploaded vectors are inconsistent. |
VECTOR_LENGTH_INVALID | 400 | LIV_0203 | ERROR | The length of the uploaded vector is incorrect. |
INPUT_VALIDATE_FAILED | 422 | LIV_0204 | ERROR | Unable to verify the subject of the current request. |
BASE64_DECODE_FAILED | 400 | LIV_0205 | ERROR | Unable to decode the Base64 encoded string. |
FACE_DETECT_FAILED | 400 | LIV_0300 | ERROR | No faces detected in the uploaded image. |
FACE_ANGLE_INVALID | 400 | LIV_0301 | ERROR | Invalid face angles detected. |
LANDMARK_POSITION_INVALID | 400 | LIV_0302 | ERROR | Invalid feature point positions detected. |
FACE_ROLL_INVALID | 400 | LIV_0303 | ERROR | Invalid face roll angles detected. |
MULTIPLE_FACES_DETECTED | 422 | LIV_0304 | ERROR | Multiple faces detected. |
ANGLE_DETECT_FAILED | 400 | LIV_0305 | ERROR | Unable to detect the correct face angles in the uploaded image. |
FACE_IS_OCCLUDED | 400 | LIV_0306 | ERROR | Faces in the uploaded image are obscured. |
FACE_LEFT_ANGLE_INVALID | 400 | LIV_0307 | ERROR | Invalid left-side face angle in the uploaded image. |
FACE_RIGHT_ANGLE_INVALID | 400 | LIV_0308 | ERROR | Invalid right-side face angle in the uploaded image. |
FACE_ANGLE_DIFFERENCE_INVALID | 400 | LIV_0309 | ERROR | Invalid difference in face angles in the uploaded image. |
ANGLE_DETECT_FAILED_OR_FACE_IS_OCCLUDED | 400 | LIV_0310 | ERROR | Unable to detect the correct face angles or faces are obscured in the uploaded image. |