Face · Standard API · eKYC Core
Compare faces
Compares the faces found in two images and returns a matched, unmatched or unsure verdict with a similarity score, plus each face's location and angle.
Request
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.
| Name | Type | Required | Description |
|---|---|---|---|
image1 | ImageData | Required | the first image has face to compare with image2. if use TS SDK, use ID card frontside |
image2 | ImageData | Required | the second image has face to compare with image1. if use TS SDK, use last frontal image |
type | string | Optional | specify the type of comparison face in special cases. If no specify, use the default. |
- If you use
base64,labelandmetadata, omit parameterid. - If you use
id(resultidis returned from Upload Image API), omit parameterbase64,labelandmetadata. - If you use
embedding, omit parametersid,base64.
{
"image1": {
"id": string,
"base64": string,
"label": string,
"metadata": string_json,
"embedding": []float64,
},
"image2": {
"id": string,
"base64": string,
"label": string,
"metadata": string_json,
"embedding": []float64,
},
"type": string
}
Sample request
curl -X POST \
https://tv-staging.trustingsocial.com/api/v1/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"
}
}
'
Response
data.compare_faces holds one entry per pair of faces, each with a result of matched, unmatched or unsure and a score for how likely it is that the two faces match (0-1). 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.
{
"data": {
"status": string, // "success" or "failure"
"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
],
"request_id": string // return request id to the client and can use request-id to check logs.
},
"errors": [
{
"code": string,
"message": string,
"detail": {
"field": string, // optional, which parameter is invalid.
... // any other information that can be useful for client
},
},
... // other errors
]
}
A comparison where the first image holds two faces and the second holds one comes back like this:
{
"data": {
"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": ""
},
"request_id": "b6e90aa2-a2d2-44bb-b4d5-cd4b92d0cdae",
"status": "success"
}
}
Failure codes
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 | image_not_found_exception | The image ID is not found in DB. |
404 | request_not_found_exception | The request ID is not found when polling result by id |
408 | request_timeout_exception | Request takes too long to process |
429 | rate_limit_exception | The number of requests exceeded your throughput limit. |
500 | internal_server_error | Some unexpected error occurs while processing the request |
The codes above are the ones documented for this endpoint. Response errors on the Overview lists the codes for the eKYC Core surface as a whole — the two lists do not match on every endpoint.