Client should call this API:
method | URL | content-type |
---|---|---|
POST | /v1/mix_compare_faces_sync | application/json |
Body:
{
"image1": {
"id": string,
"base64": string,
"label": string,
"metadata": json,
},
"image2": {
"id": string,
"base64": string,
"label": string,
"metadata": json,
}
}
Where:
key | type | required | description |
---|---|---|---|
image1 | ImageData | yes | image of the identity card's front side |
image2 | ImageData | yes | image of the selfie |
Which each image's parameters contains:
key | type | required | description |
---|---|---|---|
id | string | no | ID of them image in DB |
base64 | string | no | Base64 encoded text of image data |
label | string | no | label of the image |
metadata | dictionary | no | any key-value metadata to save with the image, both key and value should be string |
Note:
base64
, label
and metadata
(label
and metadata
of the image as described at Upload Image API), omit parameter id
.id
(result id
is returned from Upload Image API), omit parameter base64
, label
and metadata
.Clients can provide image data to the TrustVision API by specifying the ID the image by using upload API, or by sending the image data as base64-encoded text.
Authentication mechanism is described in Authentication.
curl -X POST \
https://tv-staging.trustingsocial.com/api/v1/mix_compare_faces_sync \
-H 'Authorization: TV <YOUR ACCESS KEY>:<CREATED SIGNATURE>' \
-H 'X-TV-Timestamp: 2019-04-21T18:00:15+07:00' \
-H 'Content-Type: application/json' \
-d \
'
{
"image1": {
"id": "7db00808-0416-45cf-a5cb-3b6dfbd7bb74"
},
"image2": {
"id": "a4facba3-334b-41fb-97e3-4766cb70ae29"
}
}
'
The response will be a JSON with following format:
{
"data": {
"status": string, // "success" or "failure"
"transaction_id": string, // optional
"image1": {
"id": string,
"transformed_image_id": string // optional, just in case the image is transformed
"faces": [
{
"id": string, // id of the face in image1
"bounding_box": {
"top": int, // the top edge of the box
"right": int, // the right edge of the box
"bottom": int, // the bottom edge of the box
"left": int, // the left edge of the box
"angle": int // the angle at which the box is rotated
}
},
... // other faces in image1
],
},
"image2": {
"id": string,
"transformed_image_id": string // optional, just in case the image is transformed
"faces": [
{
"id": string, // id of the face in image2
"bounding_box": {
"top": int, // the top edge of the box
"right": int, // the right edge of the box
"bottom": int, // the bottom edge of the box
"left": int, // the left edge of the box
"angle": int // the angle at which the box is rotated
}
},
... // other faces in image2
],
},
"compare_faces": [
{
"face1_id": string, // id of the face in image1
"face2_id": string, // id of the face in image2
"score": float, // how likely that face1 and face2 are matched (0-1)
"result": string // "matched", "unmatched", "unsure"
},
... // other pair of faces in image1 and image2
],
"portrait_sanity": { // only return the first issue found if any
"verdict": string, // good, image_too_blur, image_too_dark, image_too_bright, not_white_background, not_qualified, image_has_multiple_faces, image_has_no_faces, right, left, "open_eye,closed_eye", "closed_eye,open_eye", "open_eye,sunglasses", "sunglasses,open_eye", "closed_eye,closed_eye", "closed_eye,sunglasses", "sunglasses,closed_eye", "sunglasses,sunglasses"
"score": float, // range 0-1, how much confidence about the verdict
},
"card_sanity": { // only return the first issue found if any
"verdict": string, // good, image_too_blur, image_too_dark, image_too_bright, image_has_hole, image_has_cut, image_has_hole_and_cut
"score": float, // range 0-1, how much confidence about the verdict
},
"liveness_check": {
"is_live": bool, // the face is live or not
"score": float // how likely that the face is live (0-1)
},
},
"errors": [
{
"code": string,
"message": string,
"detail": {
"field": string, // optional, which parameter is invalid.
... // any other information that can be useful for client
},
},
... // other errors
]
}
In case the request processing has been finished, the HTTP status code will be
200
, and the data.status
is either "success"
or "failure"
depending on
whether the request has been successfully processed or not.
If the data.status
is "failure"
, the "errors"
field will tell you why it
failed.
error code | description |
---|---|
image_has_no_faces | the input image has no faces |
In case of any other errors, the data
field will be empty, and the server
sends one of following HTTP status code with error code:
HTTP code | error code | description |
---|---|---|
401 | access_denied_exception | You are not authorized to perform the action. |
400 | invalid_parameter_exception | Input parameter violates a constraint. |
400 | request_time_too_skewed | The X-TV-Timestamp header is expired, need a newer one. |
404 | request_not_found_exception | The request ID is not found in Memory Cache and DB. |
429 | rate_limit_exception | The number of requests exceeded your throughput limit. |
500 | internal_server_error | Some unexpected error occurs while processing the request |
{
"data": {
"status": "success",
"compare_faces": [
{
"face1_id": "abdba678-b680-4b62-bc4b-d9b8fb37e8e4",
"face2_id": "d43bf504-f1a3-4799-9bda-e5709ae7aa69",
"result": "matched",
"score": 0.7381135644418032
},
{
"face1_id": "ae7a6cd2-4f5b-45b3-955f-844b1bc6d95a",
"face2_id": "d43bf504-f1a3-4799-9bda-e5709ae7aa69",
"result": "unmatched",
"score": 0.5098310116475188
}
],
"image1": {
"faces": [
{
"bounding_box": {
"angle": 0,
"bottom": 446,
"left": 357,
"right": 550,
"top": 172
},
"id": "abdba678-b680-4b62-bc4b-d9b8fb37e8e4"
},
{
"bounding_box": {
"angle": 0,
"bottom": 530,
"left": 57,
"right": 254,
"top": 263
},
"id": "ae7a6cd2-4f5b-45b3-955f-844b1bc6d95a"
}
],
"id": "f3f6f8b5-2ac0-4734-a4b5-836c6c300b0b",
"transformed_image_id": ""
},
"image2": {
"faces": [
{
"bounding_box": {
"angle": 0,
"bottom": 369,
"left": 504,
"right": 559,
"top": 296
},
"id": "d43bf504-f1a3-4799-9bda-e5709ae7aa69"
}
],
"id": "639058a6-0631-4bfd-a718-bc72c2695daf",
"transformed_image_id": ""
},
"portrait_sanity": {
"score": 1,
"verdict": "good"
},
"card_sanity": {
"score": 1,
"verdict": "good"
},
"liveness_check": {
"is_live": true,
"score": 0.9999999862517992
}
}
}
The read id card api or ocr (optical character recognition) takes image_id as the input. Main function of this service is to extract text from supported legal documents. It also detects the location of the id card inside the uploaded image.
Client should call this API:
method | URL | content-type |
---|---|---|
POST | /v1/read_id_card_info_with_sanity | application/json |
Body:
{
"card_type": string
"image1": {
"id": string,
"base64": string,
"label": string,
"metadata": json,
},
"image2": {
"id": string,
"base64": string,
"label": string,
"metadata": json,
},
"qr1_images": [{
"id": string,
"base64": string,
"label": string,
"metadata": json,
}],
"qr2_images": [{
"id": string,
"base64": string,
"label": string,
"metadata": json,
}]
}
Where:
key | type | required | description |
---|---|---|---|
card_type | string | yes | type of identity card |
image1 | ImageData | yes | image of the identity card's front side |
image2 | ImageData | no | image of the identity card's back side |
qr1_images | List of ImageData | no | images of the QR code on the card's front side |
qr2_images | List of ImageData | no | images of the QR code on the card's back side |
card_type
should be one of following values:
card_type | description |
---|---|
in.aadhaar | India Aadhaar card |
in.pan | India PAN card |
in.voter | India voter card |
in.passport | India passport |
in.national_id | Any of India national ID versions |
vn.national_id | Any of Vietnam national ID versions |
Which each image's parameters contains:
key | type | required | description |
---|---|---|---|
id | string | no | ID of them image in DB |
base64 | string | no | Base64 encoded text of image data |
label | string | no | label of the image |
metadata | dictionary | no | any key-value metadata to save with the image, both key and value should be string |
Note:
base64
, label
and metadata
(label
and metadata
of the image as described at Upload Image API), omit parameter id
.id
(result id
is returned from Upload Image API), omit parameter base64
, label
and metadata
.Clients can provide image data to the TrustVision API by specifying the ID the image by using upload API, or by sending the image data as base64-encoded text.
Authentication mechanism is described in Authentication.
curl -X POST \
https://tv-staging.trustingsocial.com/api/v1/read_id_card_info_with_sanity \
-H 'Authorization: TV <YOUR ACCESS KEY>:<CREATED SIGNATURE>' \
-H 'X-TV-Timestamp: 2019-04-21T18:00:15+07:00' \
-H 'Content-Type: application/json' \
-d \
'
{
"card_type": "vn.national_id",
"image1": {
"id": "7db00808-0416-45cf-a5cb-3b6dfbd7bb74"
},
"image2": {
"id": "a4facba3-334b-41fb-97e3-4766cb70ae29"
}
}
'
The response will be a JSON with following format:
{
"data": {
"request_id": string, // ID of the request
"status": string, // "success" or "failure"
"image1": {
"id": string,
"transformed_image_id": string, // optional, just in case the image is transformed
"card_box": {
"top_left": { "x": float, "y": float },
"top_right": { "x": float, "y": float },
"bottom_left": { "x": float, "y": float },
"bottom_right": { "x": float, "y": float },
},
"qr": {
"parsed": [ // list of parsed information from QR code
{
"field": string, // uid, name, dateOfBirth, careOf, ...
"value": string,
},
... // other fields
],
"raw": string, // raw XML string decoded from QR code
}
"ocr": {
"parsed": [ // list of parsed information from OCR
{
"field": string, // uid, name, dateOfBirth, careOf, ...
"value": string,
},
... // other fields
],
"raw": [ // list of raw OCR text boxes
{
"text": string, // detected text
"bounding_box": [
{
"x": float,
"y": float,
},
{
"x": float,
"y": float,
},
{
"x": float,
"y": float,
},
{
"x": float,
"y": float,
}
],
"label": string, // label of the box
"line": int,
"group": int,
},
... // other text boxes
]
},
},
"image2": {
"id": string,
"transformed_image_id": string, // optional, just in case the image is transformed
"card_box": {
"top_left": { "x": float, "y": float },
"top_right": { "x": float, "y": float },
"bottom_left": { "x": float, "y": float },
"bottom_right": { "x": float, "y": float },
},
"qr": {
"parsed": [ // list of parsed information from QR code
{
"field": string, // uid, name, dateOfBirth, careOf, ...
"value": string,
},
... // other fields
],
"raw": string, // raw XML string decoded from QR code
}
"ocr": {
"parsed": [ // list of parsed information from OCR
{
"field": string, // uid, name, dateOfBirth, careOf, ...
"value": string,
},
... // other fields
],
"raw": [ // list of raw OCR text boxes
{
"text": string, // detected text
"bounding_box": [
{
"x": float,
"y": float,
},
{
"x": float,
"y": float,
},
{
"x": float,
"y": float,
},
{
"x": float,
"y": float,
}
],
"label": string, // label of the box
"line": int,
"group": int,
},
... // other text boxes
]
},
},
"card_information": [ // merged and normalized information from QR and OCR of both image1 and image2
{
"field": string, // field name ("identity_number", "full_name", "first_name, "middle_name", "last_name", "birth_date", "address_level_1_(city)", "address_level_1_(city)_code",...)
"value": string, // value of the field ("123456789", "Sohit Gour", "1998-06-23")
"confidence_verdict": string, // verdict of value ("SURE", "UNSURE", ""), empty mean Not Available. This field is shown if client enable 'enable_evaluate_confidence'
"confidence_score": float, // confidence score of predict value. This field is shown if client enable 'enable_evaluate_confidence'
},
... // other pair of card information
]
},
"errors": [
{
"code": string, // "unexpected_error", "image_too_dark", "image_too_bright", ...
"message": string, // message to clarify the error code
"detail": {
... // any information to help trace and debug
}
},
... // other errors
]
}
The data.status
is either "success"
or "failure"
depending on
whether the request has been successfully processed or not.
If the data.status
is "failure"
, the "errors"
field will tell you why it
failed.
error code | description |
---|---|
incorrect_card_type | the input image is not same type with selected card |
nocard_or_multicard_image | the input image is no card or multicard detected |
image_too_blur | the input image is too blur |
image_too_dark | the input image is too dark |
image_too_bright | the input image is too bright (glare) |
image_has_hole | the input image has hole |
image_has_cut | the input image has cut |
image_has_hole_and_cut | the input image has hole and cut |
bad_quality_card_image | the input image is bad quality |
In case of any other errors, the data
field will be empty, and the server
sends one of following HTTP status code with error code:
HTTP code | error code | description |
---|---|---|
401 | access_denied_exception | You are not authorized to perform the action. |
400 | invalid_parameter_exception | Input parameter violates a constraint. |
400 | request_time_too_skewed | The X-TV-Timestamp header is expired, need a newer one. |
404 | request_not_found_exception | The request ID is not found in Memory Cache and DB. |
429 | rate_limit_exception | The number of requests exceeded your throughput limit. |
500 | internal_server_error | Some unexpected error occurs while processing the request |
{
"data": {
"card_information": [
{
"confidence_score": 1,
"confidence_verdict": "SURE",
"digit_confidence_scores": [
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1
],
"field": "id",
"value": "012345678910"
},
{
"confidence_score": 1,
"confidence_verdict": "SURE",
"field": "name",
"value": "NGUYỄN VĂN A"
},
{
"confidence_score": 1,
"confidence_verdict": "SURE",
"field": "dob",
"value": "01/01/2001"
},
{
"confidence_score": 1,
"confidence_verdict": "SURE",
"field": "gender",
"value": "NAM"
},
{
"confidence_score": 1,
"confidence_verdict": "SURE",
"field": "address",
"value": "132 HÀM NGHI, PHƯỜNG BẾN THÀNH, QUẬN 1, TP.HỒ CHÍ MINH"
},
{
"confidence_score": 1,
"confidence_verdict": "SURE",
"field": "expiry_date",
"value": "01/01/2026"
},
{
"confidence_score": 1,
"confidence_verdict": "SURE",
"field": "issue_date",
"value": "25/07/2022"
},
...,
{
"field": "card_type",
"value": "vn.cccd_new"
},
{
"field": "card_label",
"value": "vn.cccd_new.front"
},
{
"field": "nationality",
"value": "VIỆT NAM"
}
],
"image1": {
"card_box": {
"bottom_left": {
"x": 108.75621096603572,
"y": 532.4366315092892
},
"bottom_right": {
"x": 808.5273808091879,
"y": 518.4647938594222
},
"top_left": {
"x": 119.84309555403888,
"y": 122.66592678334564
},
"top_right": {
"x": 785.999680519104,
"y": 111.78477731919848
}
},
"id": "8c72e2b0-b0d9-4c4d-bb76-5ca6262af103",
"mrz": {
"parsed": null,
"raw": null
},
"nfc": {
"parsed": null,
"raw": null
},
"ocr": {
"parsed": [
{
"confidence_score": 1,
"confidence_verdict": "SURE",
"digit_confidence_scores": [
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1
],
"field": "id",
"value": "012345678910"
},
{
"confidence_score": 1,
"confidence_verdict": "SURE",
"field": "name",
"value": "NGUYỄN VĂN A"
},
{
"confidence_score": 1,
"confidence_verdict": "SURE",
"field": "dob",
"value": "01/01/2001"
},
{
"confidence_score": 1,
"confidence_verdict": "SURE",
"field": "gender",
"value": "NAM"
},
{
"confidence_score": 1,
"confidence_verdict": "SURE",
"field": "address",
"value": "132 HÀM NGHI, PHƯỜNG BẾN THÀNH, QUẬN 1, TP.HỒ CHÍ MINH"
},
{
"confidence_score": 1,
"confidence_verdict": "SURE",
"field": "expiry_date",
"value": "01/01/2026"
},
{
"confidence_score": 1,
"confidence_verdict": "SURE",
"field": "issue_date",
"value": "25/07/2022"
},
...
],
"raw": [
{
"bounding_box": [
{
"x": 281.2383117675781,
"y": 166.15625
},
{
"x": 518.7890625,
"y": 166.15625
},
{
"x": 518.7890625,
"y": 198.109375
},
{
"x": 281.2383117675781,
"y": 198.109375
}
],
"char_probs": [
-0.000690460205078125,
-0.0007172819459810853,
-0.0007648453465662897,
-0.0007659182301722467,
-0.0007841570768505335,
-0.0008823807002045214,
-0.0008858377696014941,
-0.0008965665474534035,
-0.0009963397169485688,
-0.0009986046934500337,
-0.000998962321318686,
-0.0010205389698967338,
-0.001036274479702115,
-0.001036274479702115
],
"entropy": 0.004665346350520849,
"group": 0,
"label": 1,
"line": 0,
"text": "012345678910"
},
...
]
},
"qr": {
"parsed": [
{
"confidence_score": 1,
"confidence_verdict": "SURE",
"field": "id",
"value": "012345678910"
},
{
"confidence_score": 1,
"confidence_verdict": "SURE",
"field": "id_1",
"value": ""
},
{
"confidence_score": 1,
"confidence_verdict": "SURE",
"field": "name",
"value": "NGUYỄN VĂN A"
},
...
],
"raw": "012345678910||NGUYỄN VĂN A|01012001|Nam|132 Hàm Nghi, Phường Bến Thành, Quận 1, TP.Hồ Chí Minh|25072022"
},
"transformed_image_id": "0133973f-e0ea-43e1-97fe-6377eff3a4ff"
},
"image2": null,
"status": "success"
}
}