• About TrustVision
  • Android SDK
  • Flutter SDK
  • React Native SDK
  • iOS SDK
  • Web SDK
  • API Client Libraries
  • Integration Case Studies
  • TS eKYC/FA App
  • eKYC Platform
TrustVision API Documentation

Standard API

Authentication mechanism

We use HMAC authentication which has been widely used by Amazon and Google to grant access to many of their APIs.

How it works:

1. API Access Key

A pair of:

  • Access Key ID: a unique identifier (UUID) of the API access key.

  • Access Key Secret: a secret key that will be used to sign the requests.

TrustVision team will provide an access key pair for each customers before integration.

2. Client signs a request

Two required headers:

  • X-TV-Timestamp: Current timestamp in RFC3339 format.

    • Example: 2019-04-21T18:00:15+07:00
  • Authorization: Header value format TV {AccessKeyID}:{Signature}.

    • Example: TV a0ce69ea-cbf7-49cc-ab47-6381ed7c5cf8:Rm4qG9YHhDaaUdwQlKqPjuzgQkyobDFVfZAZrlEVFwc=

Where

  • AccessKeyID: provided by TrustVision.
  • Signature: a Base64 encoded HMAC SHA256 hash of the StringToSign, refer to the following pseudo code:
text
# Pseudo code
StringToSign = HttpMethod + "\n" + UrlPath + "\n" + Timestamp
# HttpMethod: such as `POST`, `GET`, `PUT`, `PATCH`, `DELETE`
# UrlPath: relative route path of the resource (exclude the domain). Example: `/v1/images`
# Timestamp: the time of the request in RFC3339 format. The client must also
  send this timestamp with the request in the `X-TV-Timestamp` header.

Signature = Base64(HmacSha256(AccessKeySecret, Utf8EncodingOf(StringToSign)))

Advanced: Hash the Content using MD5 and add to StringToSign

text
StringToSign = HttpMethod + "\n" + UrlPath + "\n" + Timestamp + "\n" + ContentMD5;
# ContentMD: hash whole JSON content

Note: When we use content MD5 hashing, we have to AES-256 encrypt JSON content to new JSON structure first

go
{
    "payload": string, // AES-256 encrypted content
}

Please contact the administrator for more detail.

Reference: Base64 encoded HMAC SHA256 hash (in different languages)

Sample Signature generation code:

java
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base64;
import okhttp3.*;

public class ApiSecurityExample {
  public static void main(String[] args) {
    try {

        // Provided by TV
        String accessKeyId     = "<YOUR ACCESS KEY>"
        String accessKeySecret = "<YOUR SECRET>"

        // Request info
        String method          = "POST"
        String urlPath         = "/v1/images"
        String rfc3339date    = "2019-04-21T18:00:15+07:00"

        Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
        SecretKeySpec secret_key = new SecretKeySpec(accessKeySecret.getBytes(), "HmacSHA256");
        sha256_HMAC.init(secret_key);

        // Create signature
        String stringToSign = String.format("%s\n%s\n%s", method, urlPath, rfc3339date)
        String signature = Base64.encodeBase64String(sha256_HMAC.doFinal(stringToSign.getBytes()));

        // Send request
        OkHttpClient client = new OkHttpClient().newBuilder().build();
        RequestBody body = new MultipartBody.Builder().setType(MultipartBody.FORM)
            .addFormDataPart("file","portrait.jpg",
                RequestBody.create(MediaType.parse("application/octet-stream"),
                new File("/images/portrait.jpg")))
            .addFormDataPart("label","portrait")
            .build();
        Request request = new Request.Builder()
            .url("https://tv-staging.trustingsocial.com/api/v1/images")
            .method("POST", body)
            .addHeader("Authorization", String.format("TV %s:%s", accessKeyId, signature))
            .addHeader("X-TV-Timestamp", rfc3339date)
            .build();
        Response response = client.newCall(request).execute();
    }
    catch (Exception e){
        System.out.println("Error");
    }
   }
}

Try verifying Signature using online tool, check the Base64 result to compare with your own computation.

3. Send request

Sample request detail:

KeyValue
Timestamp2019-04-21T18:00:15+07:00
HTTP VerbPOST
Staging endpointhttps://tv-staging.trustingsocial.com/api
Path/v1/images

Sample code:

bash
curl -X POST \
https://tv-staging.trustingsocial.com/api/v1/images \
-H 'Authorization: TV <YOUR ACCESS KEY>:<CREATED SIGNATURE>' \
-H 'X-TV-Timestamp: 2019-04-21T18:00:15+07:00' \
-H 'content-type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW' \
-F file=@/images/portrait.jpg \
-F label=portrait

4. Server verifies the request signature

To verify the signature, the server first takes the request timestamp from X-TV-Timestamp header, compares it with current timestamp of the server. If the difference between 2 timestamps is more than 15 minutes, it will reject the request and return RequestTimeTooSkewed error to the client. The intention of this restriction is to limit the possibility that intercepted requests could be replayed by an adversary.

If the timestamp is within the limit, the server will then parse value from Authorization header to get AccessKeyID and Signature (separated by :). It looks up AccessKeyID to get the corresponding AccessKeySecret.

After that, the server uses the request timestamp to generate the string to sign, and use the AccessKeySecret to creates the signature with the same method as described before.

Finally, the request is authorized if the generated signature matches the request signature.

Some of the APIs required user consent in order to process user's PII data.

To provide user consent for TS, client should attach the following headers to the request:

headerrequireddescription
X-UC-IPnoCurrent IP address of the end-user used during the verification
X-UC-LocationyesCurrent location of the end-user in format: <country-code>/<state-code>

- Country of end-user. Possible values: ISO 3166-1 alpha-3 country code

- State of end-user. Applicable only in countries where state exists, including USA. Possible values: For USA, CAN, or AUS alpha-2 code (state only - without country & hyphen), e.g. IL (Illinois), NSW (New South Wales). For other countries, if applicable, any string. For VNM & PHL, State is not mandatory.
X-UC-Consent-ObtainedyesConsent obtained from the end-user. Possible values: yes or no
X-UC-Consent-Obtained-AtyesTimestamp when consent was obtained from the end-user. Format: RFC3339, e.g. 2019-04-21T18:00:15+07:00

For the list of services that required user consent, please contact the admin.

Suggested scenarios (eKYC System included Face Authen services, NFC Chip verification services)

Mobile/Web App will send all requests to the Bank's Server. Bank's backend implements based on your business as call APIs (OCR, Liveness, FaceMatching, FaceRetrieval,..) to TrustingSocial Server and receives a response. And then handle the response and return the result to your application. Scenario 1

Scenario 2: Forwarding requests

Mobile/Web App will send all requests to the Bank's Server. The Bank Server attaches the authorization header and forwards all requests to the TrustingSocial Server. eKYC result will be sent back to the Mobile/Web App Scenario 2

Scenario 3: Use temporary credential or signature

Mobile/Web App will call the Bank's Server to get temporary credentials or signature. Mobile/Web App will use a temporary credential or signature to call Trusting Social. Scenario 3

Temporary signature: Recommended

Temporary credential

Scenario 4: Restrict with security

Mobile/Web App will call the TrustingSocial Server directly and receive the eKYC result. Scenario 4

Scenario Hybrid: Scenario 1 and Scenario 3

Mobile/Web App will upload images and video frames to the TrustingSocial Server directly. The Bank server will call main API services (OCR, Tampering, Liveness check, Compare Faces, Face Authen, NFC). Scenario Hybrid

Suggested scenarios (FaceAuthen System deployed On-premise or Cloud)

Mobile/Web App will send all requests to the Bank's Server. Bank's backend implements based on your business as calls APIs (Face Registration, Face Authentication) to TrustingSocial Server and receives a response. And then handle the response and return the result to your application. Scenario 1

Scenario 2: Face Authen Standalone combines with user onboarding eKYC on TS's eKYC system

Mobile/Web App will send all requests to Bank's Server. Bank's backend implements based on your business as call APIs (Face Registration, Face Authentication) to TrustingSocial Server and receives a response. And then handle the response and return the result to your application. Scenario 2

Interaction Flows

Flow 1: Compare faces between images

Flow 1: Compare faces between 2 images

Flow 2: Verify face liveness in images

We provide multi-layered liveness detection - active (challenge response-based) liveness verification and passive (AI-based) liveness verification.

Flow 2: Verify face liveness in images

Flow 3: Read ID card info

Flow 3: Read ID card info

Flow 4: Convert PDF to images

Flow 4: Convert PDF to images

Flow 5: Verify portrait sanity

Flow 5: Verify portrait sanity

Flow 6: Verify id card sanity

Flow 6: Verify id card sanity

Flow 7: Index faces

Flow 7: Index faces

Flow 8: Search faces

Flow 8: Search faces

Flow 9: Update metadata

Flow 9: Update metadata

Flow 10: Face OTP

Flow 10: Face OTP

API Reconciliation

To make easier for API reconciliation, we support some ways to reconcile requests between the client and TrustingSocial (TS) as below:

  1. Use X-Request-ID (Recommended for VN market): When the client makes any API should pass an HTTP header X-Request-Id. The client should generate and manage its value of it (max length 64 characters). When reconciling, we will compare the value that the client sent and TS received if have a mismatch Besides that, we often reconcile base users, so the client should generate a value for all APIs calls of a user.

eg. Client can generate pattern like: a UUID or [USER_ID]-[RANDOM_ID], ...

  1. Use Transaction-ID (Recommended for IN market): Reference API

API usage recommendations

Use uploaded image ID

  • Should upload image to receive image ID before passing it to other service APIs.

Image label table

Image label constants MUST be one of the following values:

labeldescriptionsupported countries
portraitthe portrait photoall
qr_codethe QR code imageall
id_card.global.passport.frontthe front side of Global passportglobal
id_card.global.passport.backthe back side of Global passportglobal
id_card.in.aadhaar.frontthe front side of India Aadhaar cardindia
id_card.in.aadhaar.backthe back side of India Aadhaar cardindia
id_card.in.pan.frontthe front side of India PAN cardindia
id_card.in.pan.backthe back side of India PAN cardindia
id_card.in.voter.frontthe front side of India Voter cardindia
id_card.in.voter.backthe back side of India Voter cardindia
id_card.in.passport.frontthe front side of India passportindia
id_card.in.passport.backthe back side of India passportindia
id_card.vn.national_id.frontthe front side of Vietnam cards(CMND old/new, CCCD, Passport)vietnam
id_card.vn.national_id.backthe back side of Vietnam cards(CMND old/new, CCCD, Passport)vietnam
id_card.vn.cmnd_old.frontthe front side of Vietnam national ID old versionvietnam
id_card.vn.cmnd_old.backthe back side of Vietnam national ID old versionvietnam
id_card.vn.cmnd_new.frontthe front side of Vietnam national ID new versionvietnam
id_card.vn.cmnd_new.backthe back side of Vietnam national ID new versionvietnam
id_card.vn.cccd.frontthe front side of Vietnam national ID latest versionvietnam
id_card.vn.cccd.backthe back side of Vietnam national ID latest versionvietnam
id_card.vn.cccd_new.frontthe front side of Vietnam national ID latest versionvietnam
id_card.vn.cccd_new.backthe back side of Vietnam national ID latest versionvietnam
id_card.vn.tcc.frontthe front side of Vietnam national ID latest version (TCC)vietnam
id_card.vn.tcc.backthe back side of Vietnam national ID latest version (TCC)vietnam
id_card.vn.passport.frontmain page of Vietnam passportvietnam
doc.vn.business_licensethe business license imagevietnam
id_card.ph.national_id.frontThe front side of the any Philippines cardphilippines
id_card.ph.national_id.backThe back side of the any Philippines cardphilippines
id_card.ph.nid.frontThe front side of the Philippines National ID Cardphilippines
id_card.ph.nid.backThe back side of the Philippines National ID Cardphilippines
id_card.ph.ump.frontThe front side of the Philippines Unified Multi-Purpose cardphilippines
id_card.ph.ump.backThe back side of the Philippines Unified Multi-Purpose cardphilippines
id_card.ph.tin.frontThe front side of the Philippines TIN cardphilippines
id_card.ph.tin.backThe back side of the Philippines TIN cardphilippines
id_card.ph.dl.frontThe front side of the Philippines Driver Licensephilippines
id_card.ph.dl.backThe back side of the Philippines Driver Licensephilippines
id_card.ph.sss.frontThe front side of the Philippines Social Security System cardphilippines
id_card.ph.sss.backThe back side of the Philippines Social Security System cardphilippines
id_card.ph.passport.frontThe front side of the Philippines passportphilippines
id_card.ph.passport.backThe back side of the Philippines passportphilippines
id_card.ph.postal.frontThe front side of the Philippines postal cardphilippines
id_card.ph.postal.backThe back side of the Philippines postal cardphilippines
id_card.ph.philhealth.frontThe front side of the Philippines PhilHealth cardphilippines
id_card.ph.philhealth.backThe back side of the Philippines PhilHealth cardphilippines
id_card.ph.prc.frontThe front side of the Philippines PRC cardphilippines
id_card.ph.prc.backThe back side of the Philippines PRC cardphilippines
id_card.ph.loyalty.frontThe front side of the Philippines loyalty cardphilippines
id_card.ph.loyalty.backThe back side of the Philippines loyalty cardphilippines

Card type table

Card types MUST be one of following values:

card_typedescriptionsupported countries
global.passportGlobal passportglobal
in.aadhaarIndia Aadhaar cardindia
in.panIndia PAN cardindia
in.voterIndia voter cardindia
in.passportIndia passportindia
in.national_idAny of India national ID versionsindia
vn.national_idAny of Vietnam national ID versionsvietnam
vn.cmnd_oldChứng minh nhân dân cũvietnam
vn.cmnd_newChứng minh nhân dân mớivietnam
vn.cccdCăn cước công dânvietnam
vn.cccd_newCăn cước công dân gắn chipvietnam
vn.tccThẻ căn cướcvietnam
vn.passportVietnam passportvietnam
ph.national_idAny of the Philippines national ID versionsphilippines
ph.nidPhilippines National ID Cardphilippines
ph.umpPhilippines Unified Multi-Purpose cardphilippines
ph.tinPhilippines TIN cardphilippines
ph.dlPhilippines Driver Licensephilippines
ph.sssPhilippines Social Security System cardphilippines
ph.passportPhilippines passportphilippines
ph.postalPhilippines postal cardphilippines
ph.philhealthPhilippines PhilHealth cardphilippines
ph.prcPhilippines PRC cardphilippines
ph.loyaltyPhilippines loyalty cardphilippines

Response errors

In case of error, the data will be empty, and server sends following HTTP status code and error information:

HTTP codeerror codedescription
401access_denied_exceptionYou are not authorized to perform the action.
413image_too_large_exceptionThe input image size exceeds the allowed limit (15MB).
415invalid_image_format_exceptionThe provided image format is not supported (JPG/PNG)
400invalid_parameter_exceptionInput parameter violates a constraint.
400request_time_too_skewedThe X-TV-Timestamp header is expired, need a newer one.
404image_not_found_exceptionThe image ID is not found in DB.
408request_timeout_exceptionRequest takes too long to process
429rate_limit_exceptionThe number of requests exceeded your throughput limit.
500internal_server_errorSome unexpected error occurs while processing the request

List of APIs

Upload Image

Upload image is the necessary step to use all of our services. When an image is uploaded, image_id will be returned which is required for all other APIs.

1. Request

Client should call this API:

methodURLcontent-type
POST/v1/imagesmultipart/form-data or application/json

With following parameters:

fieldtyperequireddescription
filefileyes if content-type is multipart/form-datathe image file to be uploaded
base64stringyes if content-type is application/jsonthe base64 of image file to be uploaded
labelstringyeslabel of the image as described at Label table
metadatastring_jsonnokey-value, key should be string, value should be string, int, float, bool. Example {\"id\":\"123456789\", \"type\": 1}
tagstringnotag of the image. India only

Note: metadata is a JSON string contains key/value as dictionary. Metadata for QR code image can contains the raw decoded string like this:

JSON
{\"raw\": \"value\"}  // raw decoded string of the QR code.

Authentication mechanism is described in Authentication.

Sample Request

bash
curl -X POST \
https://tv-staging.trustingsocial.com/api/v1/images \
-H 'Authorization: TV <YOUR ACCESS KEY>:<CREATED SIGNATURE>' \
-H 'X-TV-Timestamp: 2019-04-21T18:00:15+07:00' \
-F 'file=@"images/portrait.jpg"' \
-F 'label="portrait"'

2. Response

The response will be a JSON with following format:

javascript
{
    "data": {
        "image_id": string, // ID of the uploaded image in StoreDB
    },
    "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 of success, the HTTP status code will be 200, and the data will be an object containing following fields:

fieldtypedescription
image_idstringID of the uploaded image (UUID)

Sample Response Error

In case of error, the data will be empty, and server sends following HTTP status code and error information:

HTTP codeerror codedescription
400invalid_parameter_exceptionInput parameter violates a constraint.
400request_time_too_skewedThe X-TV-Timestamp header is expired, need a newer one.
401access_denied_exceptionYou are not authorized to perform the action.
404image_not_found_exceptionThe image ID is not found in DB.
413image_too_large_exceptionThe input image size exceeds the allowed limit (15MB).
415invalid_image_format_exceptionThe provided image format is not supported (JPG/PNG)
408request_timeout_exceptionRequest takes too long to process
429rate_limit_exceptionThe number of requests exceeded your throughput limit.
500internal_server_errorSome unexpected error occurs while processing the request

Sample Response

JSON
{
    "data": {
        "image_id": "20b457d2-cf11-4c2b-a491-8137ae6b0bc8"
    }
}

Download Image

Download image is allowed to retrieve the original image.

1. Request

Client should call this API:

methodURLcontent-type
GET/v1/images/{image_id}application/json

To get image base64, client could send header

headertyperequireddescription
X-DOWNLOAD-BASE64boolnospecify flag true if need base64 content like data:image/png;base64,iVBORw0KGgoAAAANSU...

Authentication mechanism is described in Authentication.

Sample Request

bash
curl -X GET \
https://tv-staging.trustingsocial.com/api/v1/images/7db00808-0416-45cf-a5cb-3b6dfbd7bb74 \
-H 'Authorization: TV <YOUR ACCESS KEY>:<CREATED SIGNATURE>' \
-H 'X-TV-Timestamp: 2019-04-21T18:00:15+07:00' \
-H 'Content-Type: application/json'

2. Response

In case of success, the HTTP status code will be 200, and server will send the image file as binary content.

In case of error, server will send following HTTP status code and error information in JSON format:

javascript
{
    "data": {},
    "errors": [
        {
            "code": string,
            "message": string,
            "detail": {
                "field": string, // optional, which parameter is invalid.
                ... // any other information that can be useful for client
            },
        },
        ... // other errors
    ]
}
HTTP codeerror codedescription
401access_denied_exceptionYou are not authorized to perform the action.
400request_time_too_skewedThe X-TV-Timestamp header is expired, need a newer one.
400invalid_parameter_exceptionInput parameter violates a constraint.
404image_not_found_exceptionThe image ID is not found in DB.
408request_timeout_exceptionRequest takes too long to process
429rate_limit_exceptionThe number of requests exceeded your throughput limit.
500internal_server_errorSome unexpected error occurs while processing the request

Upload video/audio/frames

When an video/audio/frames file is uploaded, file_id will be returned.

1. Request

Client should call this API:

methodURLcontent-type
POST/v1/filesmultipart/form-data or application/json

With following parameters:

fieldtyperequireddescription
filefilenothe file video/audio to be uploaded
labelstringnolabel of the file
metadatastring_jsonnokey-value, key should be string, value should be string, int, float, bool, for example "{\"id\":\"123456789\",\"type\":1}". If the content-type is application/json, metadata should be key-value string, for example {"id":"123456789", "type": 1}
parent_idstringnouuid of the parent of the file
frames[]FrameDatanolist of video frames to be uploaded

Use-Case

  • Upload video/audio then file, label are required and content-type must be multipart/form-data.
  • Upload video frames then frames is required and content-type must be application/json.

File label should be one of following values:

labeldescription
videothe video file
audiothe audio file

Each FrameData's parameters contains:

keytyperequireddescription
base64stringnobase64 encoded text of image data
labelstringnolabel of the image as described at Label table
indexintnothe index of this frame in the video
metadatastring_jsonnokey-value, key should be string, value should be string, int, float, bool, for example "{\"id\":\"123456789\",\"type\":1}". If the content-type is application/json, metadata should be key-value string, for example {"id":"123456789", "type": 1}

Note:

  • If you use file, label, metadata, omit parameter frames.
  • If you use frames, metadata, omit parameter file, label.

Authentication mechanism is described in Authentication.

Sample Request

bash
curl -X POST \
https://tv-staging.trustingsocial.com/api/v1/files \
-H 'Authorization: TV <YOUR ACCESS KEY>:<CREATED SIGNATURE>' \
-H 'X-TV-Timestamp: 2019-04-21T18:00:15+07:00' \
-F 'file=@"videos/frames.mp4"'
-F 'label="video"'

2. Response

The response will be a JSON with following format:

javascript
{
  "data": {
    "file_id": string, // ID of the uploaded file in StoreDB
  },
  "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 of success, the HTTP status code will be 200, and the data will be an object containing following fields:

fieldtypedescription
file_idstringID of the uploaded file (UUID)

Sample Response Error

In case of error, the data will be empty, and server sends following HTTP status code and error information:

HTTP codeerror codedescription
400invalid_parameter_exceptionInput parameter violates a constraint.
400request_time_too_skewedThe X-TV-Timestamp header is expired, need a newer one.
401access_denied_exceptionYou are not authorized to perform the action.
404image_not_found_exceptionThe image ID is not found in DB.
408request_timeout_exceptionRequest takes too long to process
413file_too_large_exceptionThe input file size exceeds the allowed limit (15MB).
429rate_limit_exceptionThe number of requests exceeded your throughput limit.
500internal_server_errorSome unexpected error occurs while processing the request

Sample Response

JSON
{
  "data": {
    "file_id": "20b457d2-cf11-4c2b-a491-8137ae6b0bc8"
  }
}

Download File

Download file is allowed to retrieve the original file as video, audio or pdf.

1. Request

Client should call this API:

methodURLcontent-type
GET/v1/files/{file_id}application/json

To get file base64, client could send header

headertyperequireddescription
X-DOWNLOAD-BASE64boolnospecify flag true if need base64 content like data:video/mp4;base64,iVBORw0KGgoAAAANSU...

Authentication mechanism is described in Authentication.

Sample Request

bash
curl -X GET \
https://tv-staging.trustingsocial.com/api/v1/files/7db00808-0416-45cf-a5cb-3b6dfbd7bb74 \
-H 'Authorization: TV <YOUR ACCESS KEY>:<CREATED SIGNATURE>' \
-H 'X-TV-Timestamp: 2019-04-21T18:00:15+07:00' \
-H 'Content-Type: application/json'

2. Response

In case of success, the HTTP status code will be 200, and server will send the image file as binary content.

In case of error, server will send following HTTP status code and error information in JSON format:

javascript
{
    "data": {},
    "errors": [
        {
            "code": string,
            "message": string,
            "detail": {
                "field": string, // optional, which parameter is invalid.
                ... // any other information that can be useful for client
            },
        },
        ... // other errors
    ]
}
HTTP codeerror codedescription
401access_denied_exceptionYou are not authorized to perform the action.
400invalid_parameter_exceptionInput parameter violates a constraint.
400request_time_too_skewedThe X-TV-Timestamp header is expired, need a newer one.
404image_not_found_exceptionThe image ID is not found in DB.
408request_timeout_exceptionRequest takes too long to process
429rate_limit_exceptionThe number of requests exceeded your throughput limit.
500internal_server_errorSome unexpected error occurs while processing the request

Compare faces between 2 images

The API compares faces from two image_id received from the upload image api, Main output of this service dictates if those faces belong to a person (matched, unmatched or unsure) based on a similarity score (0-1, with 0 means absolutely different face with no similarity). It also detects other attributes of the face such as its location and angle.

1. Request

Client should call this API:

methodURLcontent-type
POST/v1/compare_faces_syncapplication/json

Body:

JSON
{
    "image1": {
        "id": string,
        "base64": string,
        "label": string,
        "metadata": string_json,
    },
    "image2": {
        "id": string,
        "base64": string,
        "label": string,
        "metadata": string_json,
    },
    "type": string
}

Where

keytyperequireddescription
image1ImageDatayesthe first image has face to compare with image2. if use TS SDK, use ID card frontside
image2ImageDatayesthe second image has face to compare with image1. if use TS SDK, use last frontal image
typestringnospecify the type of comparison face in special cases. If no specify, use the default.

Which each image's parameters contains:

keytyperequireddescription
idstringnoID of image is returned from API Upload
base64stringnobase64 encoded text of image data
labelstringnolabel of the image as described at Label table
metadatastring_jsonnokey-value string, key should be string, value should be string, int, float, bool. Example "{\"id\":\"123456789\",\"type\":1}"

Note:

  • If you use base64, label and metadata, omit parameter id.
  • If you use 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.

Sample Request

bash
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"
    }
}
'

2. Response

The response will be a JSON with following format:

javascript
{
    "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
    ]
}

Note:

  • The biggest pair of faces were sorted on the top. We recommended using the first pair result in compare_faces if the selfie has multiple faces.

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 codedescription
image_has_no_facesthe 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 codeerror codedescription
401access_denied_exceptionYou are not authorized to perform the action.
400invalid_parameter_exceptionInput parameter violates a constraint.
400request_time_too_skewedThe X-TV-Timestamp header is expired, need a newer one.
404image_not_found_exceptionThe image ID is not found in DB.
404request_not_found_exceptionThe request ID is not found when polling result by id
408request_timeout_exceptionRequest takes too long to process
429rate_limit_exceptionThe number of requests exceeded your throughput limit.
500internal_server_errorSome unexpected error occurs while processing the request

Sample Response

JSON
{
    "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"
    }
}

Verify face liveness

Face Liveness or “Passive” liveness detection (versus “Active” liveness detection which requires the end user to make certain gestures such as turn left, right, etc.) takes image_id as the input. Main output of this service dictates if the image was taken from an alive person (true, false) based on liveness score (0-1, with 0 indicates an absolute fake selfie). If there is an issue with the input image like the image was too dark, too bright, too blurry or the image had no face, the service will return error in regard to the issue.

1. Request

Client should call this API:

methodURLcontent-type
POST/v1/verify_face_liveness_syncapplication/json

With following parameters:

fieldtyperequireddescription
images[]imageyesarray of frontal image object contains properties as bellow table. Active liveness: 2-4 images, Passive: 1-3 images.
gesture_images[]gesture_imagenoarray of gestures contain images. Active liveness: 3 images, Passive: no gesture image.
videos[]videonoarray of video recording when liveness on SDK. Default 1
metadatadictionarynothe collected data during liveness checking process
selfie_typestringnoSpecify the characteristic of a disabled face or liveness mode eg. disabled eye, passive, active, flash

Body:

JSON
{
    "images": [
        {
            "id": string,
            "base64": string,
            "label": string,
            "metadata": string_json,
        },
        {
            "id": string,
            "base64": string,
            "label": string,
            "metadata": string_json,
        }
    ],
    "gesture_images":[
        {
            "gesture": string,
            "images": [
                {
                        "id": string,
                        "base64": string,
                        "label": string,
                        "metadata": string_json,
                    },
                    {
                        "id": string,
                        "base64": string,
                        "label": string,
                        "metadata": string_json,
                    }
            ],
        }
    ],
    "videos": [
        {
            "id": string,
            "metadata": string_json,
            "frames": [
                {
                    "base64": string,
                    "label": string,
                    "index": int,
                    "metadata": string_json,
                },
                {
                    "base64": string,
                    "label": string,
                    "index": int,
                    "metadata": string_json,
                },
                // other frames
            ],
        },
        {
            "id": string,
            "metadata": string_json,
            "frames": [
                {
                    "base64": string,
                    "label": string,
                    "index": int,
                    "metadata": string_json,
                },
                {
                    "base64": string,
                    "label": string,
                    "index": int,
                    "metadata": string_json,
                },
                // other frames
            ],
        }
    ],
    "metadata": dictionary
}

Which each image's parameters contains:

keytyperequireddescription
idstringnoID of image is returned from API Upload
base64stringnobase64 encoded text of image data
labelstringnolabel of the image as described at Label table
metadatastring_jsonnokey-value string, key should be string, value should be string, int, float, bool. Example "{\"id\":\"123456789\",\"type\":1}"

Which each video's parameters contains:

keytyperequireddescription
idstringnoID of video is returned from API Upload
metadatastring_jsonnokey-value string, key should be string, value should be string, int, float, bool. Example "{\"id\":\"123456789\",\"type\":1}"
frames[]FrameDatanolist of video frames to be uploaded

Which FrameData's parameters contains:

keytyperequireddescription
base64stringnobase64 encoded text of image data
labelstringnolabel of the image as described at Label table
indexintnothe index of this frame in the video
metadatastring_jsonnokey-value string, key should be string, value should be string, int, float, bool. Example "{\"id\":\"123456789\",\"type\":1}"

Which each gesture_image's parameters contains:

keytyperequireddescription
gesturestringyesspecify a gesture value as bellow table. Example left, right, up or down
images[]imageyesan array of images for each gesture

Which gesture parameter contains value:

gesturesdescription
leftthe face turns left
rightthe face turns left
upthe face up
downthe face down

Which selfie_type parameter is defined as below table values

selfie_typedescription
id_cardPortrait image in Chip NFC of CCCD
lightLight Authen
passiveStandard Authen
activeAdvanced Authen uses active liveness (gestures)
flashAdvanced Authen uses full flash liveness
flash_8Edge Authen uses flash liveness with 8 frames
flash_16Edge Authen uses flash liveness with 16 frames
flash_32Advanced Authen uses flash liveness with 32 frames
flash_edgeEdge Authen uses flash liveness with minimum time
flash_advancedAdvanced Authen uses full flash liveness

Note:

  • For image, if you use base64, label and metadata, omit parameter id. If you use id (result id is returned from Upload Image API), omit parameter base64, label and metadata.
  • For video, if you use id (result id is returned from Upload File API), omit parameter frames, metadata. If you use frames, metadata, omit parameter id.
  • If you use gesture_images, the images parameter should have at least 2 images and gesture in gesture_images should have at least left or right.

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.

Sample Request

bash
curl -X POST \
https://tv-staging.trustingsocial.com/api/v1/verify_face_liveness_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 \
'
{
    "images": [
        {
            "id": "a4facba3-334b-41fb-97e3-4766cb70ae29"
        },
        {
            "id": "c5a2a405-f152-4248-b746-3af76b241ef7"
        },
        {
            "id": "5d0345f7-da7c-44e8-bd6c-a8c08c806227"
        }
    ],
    "gesture_images": [
        {
            "gesture": "left",
            "images": [
                {
                    "id": "d849a3ce-d209-4605-99a7-3d369234fd5e"
                }
            ]
        },
        {
            "gesture": "up",
            "images": [
                {
                    "id": "551fc06a-14fd-44dc-8838-abe895007c36"
                }
            ]
        },
        {
            "gesture": "right",
            "images": [
                {
                    "id": "536d2457-bfc0-4249-85f2-8c4053bdec58"
                }
            ]
        }
    ],
    "videos": [
        {
            "id": "433331b5-e1d4-433f-84e6-2260ec6bee92"
        },
        {
            "id": "3b4bf7b6-088b-4931-9279-9259f5c34fe3"
        }
    ]
}
'

2. Response

The response will be a JSON with following format:

javascript
{
    "data": {
        "status": string, "success" or "failure"
        "is_live": bool, // the face is live or not
        "score": float // how likely that the face is live (0-1)
        "images": [
            {
                "id": string, // ID of the image
                "is_live": bool, // liveness result of this image only
                "score": float // how likely that the face is live (0-1)
            },
            ... // up to 3 images
        ],
        "main_image_id": string, // optional return main image id use to compare faces and face retrieval
        "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
    ]
}

Note:

  • We should use the is_live and score results outside. These value is_live and score inside images are reference information only.

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 codedescription
image_has_no_facethe 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 codeerror codedescription
401access_denied_exceptionYou are not authorized to perform the action.
413image_too_large_exceptionThe input image size exceeds the allowed limit (15MB).
415invalid_image_format_exceptionThe provided image format is not supported (JPG/PNG)
400invalid_parameter_exceptionInput parameter violates a constraint.
400request_time_too_skewedThe X-TV-Timestamp header is expired, need a newer one.
404image_not_found_exceptionThe image ID is not found in DB.
408request_timeout_exceptionRequest takes too long to process
429rate_limit_exceptionThe number of requests exceeded your throughput limit.
500internal_server_errorSome unexpected error occurs while processing the request

Sample Response

JSON
{
    "data": {
        "details": null,
        "images": [
            {
                "id": "0e33129a-c9ec-4e22-bf53-78d496bb1f37",
                "is_live": true,
                "score": 0.981541368665434
            },
            {
                "id": "9687e2c9-4f99-46e8-a4d9-4469d61de829",
                "is_live": true,
                "score": 0.9879801868228469
            },
            {
                "id": "007b943c-eda3-4b08-8c80-da258cb69eac",
                "is_live": true,
                "score": 0.9843504686937438
            },
            {
                "id": "d98d5b5c-30e0-43c2-b812-7d53f0fc585d",
                "is_live": true,
                "score": 0.9493469735404098
            },
            {
                "id": "010b5aa5-ef2a-47fe-937d-b5d10dfad443",
                "is_live": true,
                "score": 0.9687573370988268
            },
            {
                "id": "845c3a3b-623a-4de0-8f13-e43115239e5b",
                "is_live": true,
                "score": 0.9464235386207961
            }
        ],
        "is_live": true,
        "request_id": "93029850-924c-465a-baa6-27d843cbb1ba",
        "score": 0.9999999862517992,
        "status": "success",
        "videos": [
            {
                "is_live": true,
                "score": 1
            }
        ]
    }
}

Verify face video liveness

Verify face liveness in uploaded videos.

1. Request

Client should call this API:

methodURLcontent-type
POST/v1/verify_face_video_liveness_syncapplication/json

With following parameters:

fieldtyperequireddescription
videos[]videoyesarray of video recording when liveness on SDK. Default 1

Body:

JSON
{
    "videos": [
        {
            "id": string,
            "metadata": string_json,
            "frames": [
                {
                    "base64": string,
                    "label": string,
                    "index": int,
                    "metadata": string_json,
                },
                {
                    "base64": string,
                    "label": string,
                    "index": int,
                    "metadata": string_json,
                },
                // other frames
            ],
        },
        {
            "id": string,
            "metadata": string_json,
            "frames": [
                {
                    "base64": string,
                    "label": string,
                    "index": int,
                    "metadata": string_json,
                },
                {
                    "base64": string,
                    "label": string,
                    "index": int,
                    "metadata": string_json,
                },
                // other frames
            ],
        }
    ]
}

Which each video's parameters contains:

keytyperequireddescription
idstringnoID of video is returned from API Upload
metadatastring_jsonnokey-value string, key should be string, value should be string, int, float, bool. Example "{\"id\":\"123456789\",\"type\":1}"
frames[]FrameDatanolist of video frames to be uploaded

Which FrameData's parameters contains:

keytyperequireddescription
base64stringnobase64 encoded text of image data
labelstringnolabel of the image as described at Label table
indexintnothe index of this frame in the video
metadatastring_jsonnokey-value string, key should be string, value should be string, int, float, bool. Example "{\"id\":\"123456789\",\"type\":1}"

Note:

  • If you use id (result id is returned from Upload File API), omit parameter frames, metadata. If you use frames, metadata, omit parameter id.

Authentication mechanism is described in Authentication.

Sample Request

bash
curl -X POST \
https://tv-staging.trustingsocial.com/api/v1/verify_face_video_liveness_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 \
'
{
    "videos": [
        {
            "id": "433331b5-e1d4-433f-84e6-2260ec6bee92"
        },
        {
            "id": "3b4bf7b6-088b-4931-9279-9259f5c34fe3"
        }
    ]
}
'

2. Response

The response will be a JSON with following format:

javascript
{
    "data": {
        "status": string, "success" or "failure"
        "is_live": bool, // the face is live or not
        "score": float // how likely that the face is live (0-1)
        "videos": [
            {
                "id": string, // ID of the video
                "is_live": bool, // liveness result of this video only
                "score": float // how likely that the face is live (0-1)
            },
            ... // up to 3 images
        ],
        "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
    ]
}

Note:

  • We should use the is_live and score results outside. These value is_live and score inside first element of videos are the same.

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 codedescription
image_has_no_facethe 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 codeerror codedescription
401access_denied_exceptionYou are not authorized to perform the action.
413image_too_large_exceptionThe input image size exceeds the allowed limit (15MB).
415invalid_image_format_exceptionThe provided image format is not supported (JPG/PNG)
400invalid_parameter_exceptionInput parameter violates a constraint.
400request_time_too_skewedThe X-TV-Timestamp header is expired, need a newer one.
404image_not_found_exceptionThe image ID is not found in DB.
408request_timeout_exceptionRequest takes too long to process
429rate_limit_exceptionThe number of requests exceeded your throughput limit.
500internal_server_errorSome unexpected error occurs while processing the request

Sample Response

JSON
{
    "data": {
        "is_live": true,
        "request_id": "93029850-924c-465a-baa6-27d843cbb1ba",
        "score": 0.9999999862517992,
        "status": "success",
        "videos": [
            {
                "id": "c5c7d001-0c62-4b31-8714-3bc256a8635c",
                "is_live": true,
                "score": 1
            }
        ]
    }
}

Read ID card info

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.

1. Request

Client should call this API:

methodURLcontent-type
POST/v1/read_id_card_info_syncapplication/json

Body:

JSON
{
    "card_type": string,
    "image1": {
        "id": string,
        "base64": string,
        "label": string,
        "metadata": string_json,
    },
    "image2": {
        "id": string,
        "base64": string,
        "label": string,
        "metadata": string_json,
    },
    "qr1_images": [{
        "id": string,
        "base64": string,
        "label": string,
        "metadata": string_json,
    }],
    "qr2_images": [{
        "id": string,
        "base64": string,
        "label": string,
        "metadata": string_json,
    }],
    "qr1_videos": [
            {
                "id": string,
                "metadata": string_json,
                "frames": [
                    {
                        "base64": string,
                        "label": string,
                        "index": int,
                    },
                    {
                        "base64": string,
                        "label": string,
                        "index": int,
                    },
                    // other frames
                ],
            },
            {
                "id": string,
                "metadata": string_json,
                "frames": [
                    {
                        "base64": string,
                        "label": string,
                        "index": int,
                    },
                    {
                        "base64": string,
                        "label": string,
                        "index": int,
                    },
                    // other frames
                ],
            }
       ],
}

Where

keytyperequireddescription
card_typestringyestype of identity card, described at Card type table
image1ImageDatayesimage of the identity card's front side or back side (incase image2 empty)
image2ImageDatanoimage of the identity card's back side
qr1_imagesList of ImageDatanoimages of the QR code on the card's front side
qr2_imagesList of ImageDatanoimages of the QR code on the card's back side
qr1_videos[]videonoarray of video recording QR code when capture ID Chip frontside on SDK.

Which each image's parameters contains:

keytyperequireddescription
idstringnoID of image is returned from API Upload
base64stringnobase64 encoded text of image data
labelstringnolabel of the image as described at Label table
metadatastring_jsonnokey-value string, key should be string, value should be string, int, float, bool. Example "{\"id\":\"123456789\",\"type\":1}"

Which each video's parameters contains:

keytyperequireddescription
idstringnoID of video is returned from API Upload
metadatastring_jsonnokey-value string, key should be string, value should be string, int, float, bool. Example "{\"id\":\"123456789\",\"type\":1}"
frames[]FrameDatanolist of video frames to be uploaded

Which FrameData's parameters contains:

keytyperequireddescription
base64stringnobase64 encoded text of image data
labelstringnolabel of the image as described at Label table
indexintnothe index of this frame in the video

Note:

  • If you use base64, label and metadata, omit parameter id.
  • If you use 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.

Sample Request

bash
curl -X POST \
https://tv-staging.trustingsocial.com/api/v1/read_id_card_info_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 \
'
{
    "card_type": "vn.national_id",
    "image1": {
        "id": "7db00808-0416-45cf-a5cb-3b6dfbd7bb74"
    },
    "image2": {
        "id": "a4facba3-334b-41fb-97e3-4766cb70ae29"
    }
}
'

2. Response

The response will be a JSON with following format:

javascript
{
    "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,
                "face_image_id": string, // the extracted image from Secure QR, it's available for India only
            }
            "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
                ]
            },
            "mrz": {
                "parsed": [ // list of parsed information from mrz
                    {
                        "field": string, // id no, name, dateOfBirth,...
                        "value": string,
                    },
                    ... // other fields
                ],
                "raw": [ // list of raw OCR text boxes of MRZ's area
                    {
                        "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
                "face_image_id": string, // the extracted image from Secure QR, it's available for India only
            }
            "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
                ]
            },
            "mrz": {
                "parsed": [ // list of parsed information from mrz
                    {
                        "field": string, // id no, name, dateOfBirth,...
                        "value": string,
                    },
                    ... // other fields
                ],
                "raw": [ // list of raw OCR text boxes of MRZ's area
                    {
                        "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
        ],
        "request_id": string // return request id to the client and can use request-id to check logs.
    },
    "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 codedescriptionsupported countries
nocard_or_multicard_imagethe input image is no cardall
grayscale_cardthe input image is grayscaleindia
bad_quality_card_imagethe input image has bad qualityindia
incorrect_card_typethe input image is not same type with selected cardindia
incorrect_card_sidethe input card side is incorrectindia

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 codeerror codedescription
401access_denied_exceptionYou are not authorized to perform the action.
400invalid_parameter_exceptionInput parameter violates a constraint.
400request_time_too_skewedThe X-TV-Timestamp header is expired, need a newer one.
404image_not_found_exceptionThe image ID is not found in DB.
404request_not_found_exceptionThe request ID is not found when polling result by id
408request_timeout_exceptionRequest takes too long to process
429rate_limit_exceptionThe number of requests exceeded your throughput limit.
500internal_server_errorSome unexpected error occurs while processing the request

Sample Response

JSON
{
  "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"
  }
}

Convert PDF to images

The convert pdf to image service takes a pdf file as the input. Main function of this service is to convert each page of the pdf into an image. Therefore, output will be a list of image_id each of which is respective to a page in the uploaded pdf.

1. Request

Client should call this API:

methodURLcontent-type
POST/v1/convert_pdf_syncmultipart/form-data

With following parameters:

fieldtyperequireddescription
filefileyesthe PDF file to be uploaded
pagesarray of json objectyeslist of pages to convert to images with their labels and metadata
metadatadictionarynokey-value, key should be string, value should be string

Where each object in pages has following json format:

JSON
{
    "index": int, // index of the page, starts from 1
    "label": string, // label of the page image
    "metadata": {...}, // optional, any key-value metadata to store with the page image
}

Sample Request

bash
curl -X POST \
https://tv-staging.trustingsocial.com/api/v1/convert_pdf_sync \
-H 'Authorization: TV <YOUR ACCESS KEY>:<CREATED SIGNATURE>' \
-H 'X-TV-Timestamp: 2019-04-21T18:00:15+07:00' \
-F 'file=@"portrait.pdf"' \
-F 'pages="[{\"index\":1, \"label\": \"portrait\"}]"'

2. Response

The response will be a JSON with following format:

javascript
{
    "data": {
        "status": string, "success" or "failure"
        "images": [ // list of converted images
            {
                "id": string, // ID of the image
                "page" int, // page number (1-indexed) in the PDF file
                "label": string, // label of the image
            },
        ],
        "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
    ]
}

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 codedescription
page_does_not_existThe page number doesn't exist in the PDF file

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 codeerror codedescription
401access_denied_exceptionYou are not authorized to perform the action.
413file_too_large_exceptionThe input file size exceeds the allowed limit (15MB).
415invalid_file_format_exceptionThe provided file format is not supported (PDF).
400invalid_parameter_exceptionInput parameter violates a constraint.
400request_time_too_skewedThe X-TV-Timestamp header is expired, need a newer one.
404image_not_found_exceptionThe image ID is not found in DB.
408request_timeout_exceptionRequest takes too long to process
429rate_limit_exceptionThe number of requests exceeded your throughput limit.
500internal_server_errorSome unexpected error occurs while processing the request

Sample Response

JSON
{
    "data": {
        "images": [
            {
                "id": "081083a6-55e1-4eae-9c54-523edbae4390",
                "label": "portrait",
                "page": 1
            }
        ],
        "request_id": "0866d821-9548-4445-936c-3a593345fe11",
        "status": "success"
    }
}

Request verify portrait

The verify portrait service takes an image_id as the input (should be image_id of a portrait image). Main function of this service is to check the sanity of the portrait image. This step is recommended before using other services related to portraits such as compare faces, face liveness. The output of this service is the statement of quality of the input portrait such as good or image_too_dark, image_too_blur, etc.

1. Request

Client should call this API:

methodURLcontent-type
POST/v1/verify_portrait_sanity_syncapplication/json

Body:

JSON
{
    "image": {
        "id": string,
        "base64": string,
        "label": string,
        "metadata": string_json,
    },
    "selfie_type": string,
}

Where

keytyperequireddescription
imagestringyesportrait image. if use TS SDK, use last frontal image
selfie_typestringnoSpecify the characteristic of a disabled face or liveness mode eg. disabled eye, passive, active, flash

Which image's parameters contains:

keytyperequireddescription
idstringnoID of image is returned from API Upload
base64stringnobase64 encoded text of image data
labelstringnolabel of the image as described at Label table
metadatastring_jsonnokey-value string, key should be string, value should be string, int, float, bool. Example "{\"id\":\"123456789\",\"type\":1}"

Which selfie_type parameter is defined as below table values

selfie_typedescription
id_cardPortrait image in Chip NFC of CCCD
lightLight Authen
passiveStandard Authen
activeAdvanced Authen use active liveness (gestures)
flashAdvanced Authen uses full flash liveness
flash_8Edge Authen uses flash liveness with 8 frames
flash_16Edge Authen uses flash liveness with 16 frames
flash_32Advanced Authen uses flash liveness with 32 frames
flash_edgeEdge Authen uses flash liveness with minimum time
flash_advancedAdvanced Authen uses full flash liveness

Note:

  • If you use base64, label and metadata, omit parameter id.
  • If you use 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.

Sample Request

bash
curl -X POST \
https://tv-staging.trustingsocial.com/api/v1/verify_portrait_sanity_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 \
'
{
    "image": {
        "id": "7db00808-0416-45cf-a5cb-3b6dfbd7bb74"
    }
}
'

2. Response

The response will be a JSON with following format:

javascript
{
    "data": {
        "status": string, "success" or "failure"
        "portrait_sanity": { // only return the first issue found if any
            "verdict": string, // "good" or some alerts, see below.
            "score": float, // range 0-1, how much confidence about the verdict
        },
        "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
    ]
}

Possible data.portrait_sanity.verdict is good or one of the following values corresponding to each check:

verdictsupported countries
image_too_blurvietnam, india, philippines
image_too_darkvietnam, india, philippines
image_too_brightvietnam, india, philippines
face_too_darkvietnam, india, philippines
face_too_brightvietnam, india, philippines
image_has_no_facesvietnam, india, philippines
image_has_multiple_facesvietnam, india, philippines
not_white_backgroundindia
rightvietnam, india, philippines
leftvietnam, india, philippines
not_qualifiedvietnam, india, philippines
open_eye,closed_eyevietnam, india, philippines
closed_eye,open_eyevietnam, india, philippines
open_eye,sunglassesvietnam, india, philippines
sunglasses,open_eyevietnam, india, philippines
closed_eye,closed_eyevietnam, india, philippines
closed_eye,sunglassesvietnam, india, philippines
sunglasses,closed_eyevietnam, india, philippines
face_too_smallvietnam, india, philippines
face_too_bigvietnam, india, philippines

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.

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 codeerror codedescription
401access_denied_exceptionYou are not authorized to perform the action.
400invalid_parameter_exceptionInput parameter violates a constraint.
400request_time_too_skewedThe X-TV-Timestamp header is expired, need a newer one.
404image_not_found_exceptionThe image ID is not found in DB.
408request_timeout_exceptionRequest takes too long to process
429rate_limit_exceptionThe number of requests exceeded your throughput limit.
500internal_server_errorSome unexpected error occurs while processing the request

Sample Response

JSON
{
  "data": {
    "image": {
      "id": "4368143d-9066-4f3d-ab22-4e0b6dd9b274"
    },
    "portrait_sanity": {
      "score": 1,
      "verdict": "good"
    },
    "status": "success"
  }
}

Request verify ID card

The verify ID card service takes one or two image_id as the input (should be image_id of ID card images). Main function of this service is to check the sanity of the ID card image. This step is recommended before using other services related to ID cards such as read ID card info, compare face. The output of this service is the statement of the quality of the input ID card such as good or image_too_dark, image_too_blur, etc.

1. Request

Client should call this API:

methodURLcontent-type
POST/v1/verify_id_card_sanity_syncapplication/json

Body:

JSON
{
    "card_type": string,
    "image1": {
        "id": string,
        "base64": string,
        "label": string,
        "metadata": string_json,
    },
    "image2": {
        "id": string,
        "base64": string,
        "label": string,
        "metadata": string_json,
    },
    "special_id_type": string,
}

Where

keytyperequireddescription
card_typestringyestype of identity card, described at Card type table
image1stringyesimage of the identity card's front side or back side (incase image2 empty)
image2stringnoimage of the identity card's back side
special_id_typestringnoid string (provided by admin) to identify special use-case. Omit this param to use the default.

Which each image's parameters contains:

keytyperequireddescription
idstringnoID of image is returned from API Upload
base64stringnobase64 encoded text of image data
labelstringnolabel of the image as described at Label table
metadatastring_jsonnokey-value string, key should be string, value should be string, int, float, bool. Example "{\"id\":\"123456789\",\"type\":1}"

Note:

  • If you use base64, label and metadata, omit parameter id.
  • If you use 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.

Sample Request

bash
curl -X POST \
https://tv-staging.trustingsocial.com/api/v1/verify_id_card_sanity_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 \
'
{
    "card_type": "vn.national_id",
    "image1": {
        "id": "7db00808-0416-45cf-a5cb-3b6dfbd7bb74"
    },
    "image2": {
        "id": "a4facba3-334b-41fb-97e3-4766cb70ae29"
    }
}
'

2. Response

The response will be a JSON with following format:

javascript
{
    "data": {
        "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": int, "y": int },
                "top_right": { "x": int, "y": int },
                "bottom_left": { "x": int, "y": int },
                "bottom_right": { "x": int, "y": int },
            },
        },
        "image2": {
            "id": string,
            "transformed_image_id": string // optional, just in case the image is transformed
            "card_box": {
                "top_left": { "x": int, "y": int },
                "top_right": { "x": int, "y": int },
                "bottom_left": { "x": int, "y": int },
                "bottom_right": { "x": int, "y": int },
            },
        },
        "card_sanity": { // only return the first issue found if any
            "verdict": string, // "good" or some alerts, see below.
            "score": float, // range 0-1. if verdict=good, then score=1, other verdicts the higher value denotes the more possibility the card is unqualified.
            "info": string, // optional. eg. return the last 6 digits of the CCCD Chip via this field.
        },
        "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
    ]
}

Possible data.card_sanity.verdict is good or one of the following values corresponding to each check:

verdictsupported countries
image_too_blurvietnam, india, philippines
image_too_darkvietnam, india, philippines
image_too_brightvietnam, india, philippines
image_has_holevietnam, india, philippines
image_has_cutvietnam, india, philippines
image_has_hole_and_cutvietnam, india, philippines
image_nonliveindia
{image_name}_{alert} (see the note below)vietnam, philippines
incompletevietnam, philippines
qr_not_readablevietnam, philippines

Note:

  • The image_name could be image1 or image2.
  • The alert is one of {blurry, dirty, too_dark, too_bright, glare, glare_safe, glare_unsafe} #### Where:
  • glare: image has glare spot, could be anywhere on the image.
  • glare_safe: there's glare but outside the regions containing essential information such as ID number, name, DoB and so on.
  • glare_unsafe: similar to glare_safe, but inside such important regions, may affect OCR result.

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.

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 codeerror codedescription
401access_denied_exceptionYou are not authorized to perform the action.
400invalid_parameter_exceptionInput parameter violates a constraint.
400request_time_too_skewedThe X-TV-Timestamp header is expired, need a newer one.
404image_not_found_exceptionThe image ID is not found in DB.
408request_timeout_exceptionRequest takes too long to process
429rate_limit_exceptionThe number of requests exceeded your throughput limit.
500internal_server_errorSome unexpected error occurs while processing the request

Sample Response

JSON
{
  "data": {
    "card_sanity": {
      "score": 1,
      "verdict": "good"
    },
    "image1": {
      "card_box": null,
      "id": "3ebebfe1-cf6c-4c7a-bee2-2dba834a6f1d",
      "transformed_image": null
    },
    "image2": null,
    "status": "success"
  }
}

Request detect ID Card tampering

The ID Card tampering aims to detect if an ID card was tampered with, either physically or digitally. The input of this service is one or two image_id of ID card images. The output of this service is the prediction if these ID cards were tampered with, such as tampered, hole, cut, etc. or good.

1. Request

Client should call this API:

methodURLcontent-type
POST/v1/detect_id_card_tampering_syncapplication/json

Body:

JSON
{
    "image": {
        "id": string,
        "base64": string,
        "label": string,
        "metadata": string_json,
    },
        "image2": {
        "id": string,
        "base64": string,
        "label": string,
        "metadata": string_json,
    },
    "qr1_images": [{
        "id": string,
        "base64": string,
        "label": string,
        "metadata": string_json,
    }],
    "qr2_images": [{
        "id": string,
        "base64": string,
        "label": string,
        "metadata": string_json,
    },
    "card_type": string,
    "level": string,
    "videos": [
        {
            "id": string,
            "metadata": string_json,
            "frames": [
                {
                    "base64": string,
                    "label": string,
                    "index": int,
                },
                {
                    "base64": string,
                    "label": string,
                    "index": int,
                },
                // other frames
            ],
        },
        {
            "id": string,
            "metadata": string_json,
            "frames": [
                {
                    "base64": string,
                    "label": string,
                    "index": int,
                },
                {
                    "base64": string,
                    "label": string,
                    "index": int,
                },
                // other frames
            ],
        }
    ],
    "qr1_videos": [
        {
            "id": string,
            "metadata": string_json,
            "frames": [
                {
                    "base64": string,
                    "label": string,
                    "index": int,
                },
                {
                    "base64": string,
                    "label": string,
                    "index": int,
                },
                // other frames
            ],
        },
        {
            "id": string,
            "metadata": string_json,
            "frames": [
                {
                    "base64": string,
                    "label": string,
                    "index": int,
                },
                {
                    "base64": string,
                    "label": string,
                    "index": int,
                },
                // other frames
            ],
        }
    ],
}

Where

keytyperequireddescription
imagestringyesimage of the identity card's front side. Do not use back side for this param
image2stringnoimage of the identity card's back side
qr1_imagesList of ImageDatanoimages of the QR code on the card's front side
qr2_imagesList of ImageDatanoimages of the QR code on the card's back side
card_typestringnotype of identity card, described at Card type table .Default is vn.national_id
levelstringnospecify deeply level to check tamper. Default is fully check
videos[]videonoarray of video recording when detect id card tampering on SDK.
qr1_videos[]videonoarray of video recording QR code when capture ID Chip frontside on SDK.

level values please contact the administrator.

Which each image's parameters contains:

keytyperequireddescription
idstringnoID of image is returned from API Upload
base64stringnobase64 encoded text of image data
labelstringnolabel of the image as described at Label table
metadatastring_jsonnokey-value string, key should be string, value should be string, int, float, bool. Example "{\"id\":\"123456789\",\"type\":1}"

Which each video's parameters contains:

keytyperequireddescription
idstringnoID of video is returned from API Upload
metadatastring_jsonnokey-value string, key should be string, value should be string, int, float, bool. Example "{\"id\":\"123456789\",\"type\":1}"
frames[]FrameDatanolist of video frames to be uploaded

Which FrameData's parameters contains:

keytyperequireddescription
base64stringnobase64 encoded text of image data
labelstringnolabel of the image as described at Label table
indexintnothe index of this frame in the video

Note:

  • For image, if you use base64, label and metadata, omit parameter id. If you use id (result id is returned from Upload Image API), omit parameter base64, label and metadata.
  • For video, if you use id (result id is returned from Upload Image API), omit parameter frames, metadata. If you use frames, metadata, omit parameter id.

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.

Sample Request

bash
curl -X POST \
https://tv-staging.trustingsocial.com/api/v1/detect_id_card_tampering_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 \
'
{
    "card_type": "vn.national_id",
    "image": {
        "id": "7db00808-0416-45cf-a5cb-3b6dfbd7bb74"
    },
    "image2": {
        "id": "a4facba3-334b-41fb-97e3-4766cb70ae29"
    }
}
'

2. Response

The response will be a JSON with following format:

Javascript
{
    "data": {
        "status": string, // "success" or "failure"
        "card_tampering":
        {
            "score": float,
            "verdict": string // final verdict. Reference to the verdict values table.
            "details":[ // list of results for each checked feature.
                {
                    "verdict": string, // verdict result on this checked feature. Reference to the verdict values table.
                    "score": float,
                    "info": string, // optional, information returned with this feature. Available with tax_name_unmatched verdict.
                },
                ... // other
            ]
        },
        "image_id": string, // ID of the image
        "image2_id":string, // ID of the 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
    ]
}

Verdict table: Please contact the administrator.

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.

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 codeerror codedescription
401access_denied_exceptionYou are not authorized to perform the action.
400invalid_parameter_exceptionInput parameter violates a constraint.
400request_time_too_skewedThe X-TV-Timestamp header is expired, need a newer one.
404image_not_found_exceptionThe image ID is not found in DB.
408request_timeout_exceptionRequest takes too long to process
429rate_limit_exceptionThe number of requests exceeded your throughput limit.
500internal_server_errorSome unexpected error occurs while processing the request

Sample Response

JSON
{
  "data": {
    "card_tampering": {
      "details": [
        {
          "name": "alert_1",
          "score": 1,
          "verdict": "card_expired"
        }
      ],
      "score": 1,
      "verdict": "alert"
    },
    "image2_id": "185aed08-53c7-433d-8dcd-e99f5131230f",
    "image_id": "4ba8de0e-9758-43fb-ac65-6f32ad3392d1",
    "status": "success"
  }
}

Detect faces

The Detect faces api takes an image with face and vectorize face to embedding vector.

1. Request

Client should call this API:

methodURLcontent-type
POST/v1/detect_faces_syncapplication/json

Body:

JSON
{
    "image": {
        "id": string,
        "base64": string,
        "label": string,
        "metadata": string_json,
    },
    "return_embedding": bool,
}

Where

keytyperequireddescription
imageImageDatayesimage to index face. Should use image has the face
return_embeddingboolnorequest to get face embedding or no

Which each image's parameters contains:

keytyperequireddescription
idstringnoID of image is returned from API Upload
base64stringnobase64 encoded text of image data
labelstringnolabel of the image as described at Label table
metadatastring_jsonnokey-value string, key should be string, value should be string, int, float, bool. Example "{\"id\":\"123456789\",\"type\":1}"

Which type's parameter contains value:

valuedescription
1Matching ID vs ID
2Matching ID vs Selfie
3Matching Selfie vs Selfie

Note:

  • If you use base64, label and metadata, omit parameter id.
  • If you use 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.

Sample Request

bash
curl -X POST \
https://tv-staging.trustingsocial.com/api/v1/detect_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 \
'
{
    "image": {
        "id": "7db00808-0416-45cf-a5cb-3b6dfbd7bb74"
    }
}
'

2. Response

The response will be a JSON body with following format:

JSON
{
    "data": {
        "request_id": string,
        "status": string, // "success" or "failure"
        "image": {
            "id": string,
            "transformed_image_id": string // optional, just in case the image is transformed
            "faces": [
                {
                    "id": string, // id of the face in image
                    "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
                    },
                    "embedding": []float, // embedding of face
                },
                ... // other faces in image
            ],
        },
    },
    "errors": [
        {
            "code": string,
            "message": string,
            "detail": {
                "field": string, // optional, which parameter is invalid.
                ... // any other information that can be useful for client
            },
        },
        ... // other errors
    ]
}

Note:

  • The biggest faces were sorted on the top. We recommended using the first result in faces if the input image has multiple faces.

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.

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 codeerror codedescription
401access_denied_exceptionYou are not authorized to perform the action.
400invalid_parameter_exceptionInput parameter violates a constraint.
400request_time_too_skewedThe X-TV-Timestamp header is expired, need a newer one.
404image_not_found_exceptionThe image ID is not found in DB.
404request_not_found_exceptionThe request ID is not found when polling result by id
408request_timeout_exceptionRequest takes too long to process
429rate_limit_exceptionThe number of requests exceeded your throughput limit.
500internal_server_errorSome unexpected error occurs while processing the request

Sample Response

JSON
{
  "data": {
    "image": {
      "faces": [
        {
          "bounding_box": {
            "angle": 0,
            "bottom": 568,
            "left": 123,
            "right": 257,
            "top": 402
          },
          "embedding": [
            0.09560582041740417,
            -0.15577684342861176,
            -0.009643876925110817,
            -0.019479934126138687,
            0.0861940085887909,
            -0.016617512330412865,
            ...
          ],
          "id": "2cc3a440-3390-407a-914c-66a63e6eda33"
        }
      ],
      "id": "e5e32ef1-296e-4385-8f23-9eb7e6512800",
      "transformed_image_id": ""
    },
    "status": "success"
  }
}

Face OTP

The API compares faces from two image_id received from the upload image api (one for the newly taken selfie, one for the original image). Main output of this service dictates if those faces belong to a person (matched, unmatched or unsure) based on a similarity score (0-1, with 0 means absolutely different face with no similarity). It also detects other attributes of the face such as its location and angle.

1. Request

Client should call this API:

methodURLcontent-type
POST/v1/face_otpapplication/json

Body:

JSON
{
    "selfie": [{
        "id": string,
        "base64": string,
    }],
    "original": {
        "id": string,
        "base64": string
    }
}

Where

keytyperequireddescription
idstringnoID of them image in DB
base64stringnoBase64 encoded text of image1 data

Note:

  • If you use base64, label and metadata (label and metadata of the image as described at Upload Image API), omit parameter id.
  • If you use id (result id is returned from Upload Image API), omit parameter base64, label and metadata.
  • Upto 3 selfie images can be provided all of them will be used for liveness verification, but only the first selfie image will be used for comparing faces
  • Atleast one selfie image should be provided
  • The original and the selfie image should not contain more than 1 face

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.

Sample Request

bash
curl -X POST \
https://tv-staging.trustingsocial.com/api/v1/face_otp \
-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 \
'
{
    "selfie": [
        {
            "id": "7db00808-0416-45cf-a5cb-3b6dfbd7bb74"
        }
    ],
    "original": {
        "id": "a4facba3-334b-41fb-97e3-4766cb70ae29"
    }
}
'

2. Response

The response will be a JSON with following format:

JSON
{
    "data": {
        "status": string, // "success" or "failure"
        "is_live": bool, // the face is live or not
        "compare_faces": {
            "score": float, // how likely that face1 and face2 are matched (0-1)
            "result": string // "matched", "unmatched", "unsure"
        },
        "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
    ]
}

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.

fieldsdescription
is_livethe boolean to tell the selfie is live or not
compare_faceshave result (matched/unmatched) and score

If the data.status is "failure", the "errors" field will tell you why it failed.

error codedescription
image_has_no_facethe input image has no faces
image_has_no_facesthe input image has no faces. (same with the above)
image_has_multiple_facesthe input image has multiple faces
image_too_blurthe input image is too blur
image_too_darkthe input image is too dark
image_too_brightthe input image is too bright (glare)
bad_quality_card_imagethe input image is bad quality
not_qualifiedthe input image is bad quality
not_white_backgroundthe image was not taken with a white background
face_too_darkthe face is too dark
face_too_brightthe face is too bright
face_too_smallthe face is too small
face_too_bigthe face is too big
rightthe face is turned right
leftthe face is turned left
open_eye,closed_eyethe face has eye(s) closed
closed_eye,open_eyethe face has eye(s) closed
open_eye,sunglassesthe face has sunglasses
sunglasses,open_eyethe face has sunglasses
closed_eye,closed_eyethe face has eye(s) closed
closed_eye,sunglassesthe face has sunglasses
sunglasses,closed_eyethe face has sunglasses
sunglasses,sunglassesthe face has sunglasses

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 codeerror codedescription
401access_denied_exceptionYou are not authorized to perform the action.
400invalid_parameter_exceptionInput parameter violates a constraint.
400incorrect_number_of_facesSelfie or original image have more than 1 faces.
404image_not_found_exceptionThe image ID is not found in DB.
404request_not_found_exceptionThe request ID is not found in Memory Cache and DB.
408request_timeout_exceptionRequest takes too long to process
429rate_limit_exceptionThe number of requests exceeded your throughput limit.
500internal_server_errorSome unexpected error occurs while processing the request

Sample Response

JSON
{
  "data": {
    "compare_faces": {
      "face1_id": "349ac5cd-2bd1-4bff-8c10-1cdacdd4c66d",
      "face2_id": "57263098-9c07-4220-888f-f8c4b73d4c1d",
      "result": "matched",
      "score": 0.9256071887745998
    },
    "is_live": true,
    "status": "success"
  },
  "errors": null
}

Index faces

The index faces service allows one to index an image and add it to a collection. The purpose of this activity is to build a collection of faces that can be retrieved using search faces api.

1. Request

Client should call this API:

methodURLcontent-type
POST/v1/index_faces_syncapplication/json

Body:

JSON
{
    "image": {
        "id": string,
        "base64": string,
        "label": string,
        "metadata": string_json,
    },
    "enable_update_metadata": bool,
    "collection": string,
    "type": int
}

Where

keytyperequireddescription
imageImageDatayesimage to index face. Should use image has the face. if use TS SDK, use last frontal image
enable_update_metadataboolnoAllow image.metadata to be updated.
collectionstringnoindex faces to this collection. case-sensitive
typeintnotype of collection

Which each image's parameters contains:

keytyperequireddescription
idstringnoID of image is returned from API Upload
base64stringnobase64 encoded text of image data
labelstringnolabel of the image as described at Label table
metadatastring_jsonnokey-value string, key should be string, value should be string, int, float, bool. Example "{\"id\":\"123456789\",\"type\":1}"

Which type's parameter contains value:

valuedescription
3Matching Selfie vs Selfie

Note:

  • If you use base64, label and metadata, omit parameter id.
  • If you use id (result id is returned from Upload Image API), omit parameter base64, label and metadata.
  • If not set collection, default collection will be used.

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.

Sample Request

bash
curl -X POST \
https://tv-staging.trustingsocial.com/api/v1/index_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 \
'
{
    "image": {
        "id": "a4facba3-334b-41fb-97e3-4766cb70ae29"
    }
}
'

2. Response

JSON
{
    "data": {
        "request_id": string,
        "image": {
          "id": string, // id of the image
          "transformed_image_id": string // optional, just in case the image is transformed
        },
        "status": string, // "success" or "failure"
    },
    "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.

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 codeerror codedescription
401access_denied_exceptionYou are not authorized to perform the action.
400invalid_parameter_exceptionInput parameter violates a constraint.
400request_time_too_skewedThe X-TV-Timestamp header is expired, need a newer one.
404image_not_found_exceptionThe image ID is not found in DB.
404request_not_found_exceptionThe request ID is not found when polling result by id
408request_timeout_exceptionRequest takes too long to process
429rate_limit_exceptionThe number of requests exceeded your throughput limit.
500internal_server_errorSome unexpected error occurs while processing the request

Sample Response

JSON
{
    "data": {
        "status": "success",
        "image": {
          "id": "a4facba3-334b-41fb-97e3-4766cb70ae29"
        },
        "request_id": "dfdef016-e89b-4da4-ae17-5844f909c947"
    }
}

Search faces

The search faces api takes an image_id with face and retrieves faces similar to that out of a defined collection or list collections. Each matched face will be returned with a score of similarity (similar to compare faces service) and metadata embedded with them.

1. Request

Client should call this API:

methodURLcontent-type
POST/v1/search_faces_syncapplication/json

Body:

JSON
{
    "image": {
        "id": string,
        "base64": string,
        "label": string,
        "metadata": string_json,
    },
    "collection": string,
    "collections": []string,
    "type": int,
    "special_id_type": string,
    "max_faces": int
}

Where

keytyperequireddescription
imageImageDatayesimage to index face. Should use image has the face. if use TS SDK, use last frontal image
collectionstringnosearch faces in this collection. If empty, the default collection will be used. case-sensitive
collections[]stringnosearch faces in these collections. Omit collection param if using this param. case-sensitive
typeintnotype of collection
max_facesintnomaximum face results. Default is 10
special_id_typestringnoid string (provided by admin) to identify special use-case. Omit this param to use the default.

Which each image's parameters contains:

keytyperequireddescription
idstringnoID of image is returned from API Upload
base64stringnobase64 encoded text of image data
labelstringnolabel of the image as described at Label table
metadatastring_jsonnokey-value string, key should be string, value should be string, int, float, bool. Example "{\"id\":\"123456789\",\"type\":1}"

Which type's parameter contains value:

valuedescription
3Matching Selfie vs Selfie

Note:

  • If you use base64, label and metadata, omit parameter id.
  • If you use id (result id is returned from Upload Image API), omit parameter base64, label and metadata.
  • If not set collection, default collection will be used.
  • If you specify collections not empty, we will search in list collections. otherwise, we use collection.

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.

Sample Request

bash
curl -X POST \
https://tv-staging.trustingsocial.com/api/v1/search_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 \
'
{
    "image": {
        "id": "a4facba3-334b-41fb-97e3-4766cb70ae29"
    }
}
'

2. Response

The response will be a JSON body with following format:

JSON
{
    "data": {
        "request_id": string,
        "status": string, // "success" or "failure"
        "image": {
          "id": string, // id of the image
          "transformed_image_id": string // optional, just in case the image is transformed
        },
        "faces": [   // Result for single collection. support search multiple faces. Each array is result of each face
            [
                {
                    "id": string, // id of the face in image
                    "image_id": string, // id of original image
                    "score": float, // score similar between 2 faces
                    "metadata": [ // list of meta data information of this face
                            {
                                "field": string, // application_id, national_id, ...
                                "value": primitive_type, // when index key=value then the value should a primitive type as string, int, float, boolean
                            },
                            ... // other fields
                },
                ... // other face matched of first face in image
            ],
            [
                ... // list face matches of another face in image
            ],
        ],
        "faces_in_collection": {
            "collection_name1":[   // Result for multiple collections. support search multiple faces. Each array is result of each face
                    [
                    {
                        "id": string, // id of the face in image
                        "image_id": string, // id of original image
                        "score": float, // score similar between 2 faces
                        "metadata": [ // list of meta data information of this face
                                {
                                    "field": string, // application_id, national_id, ...
                                    "value": primitive_type, // when index key=value then the value should a primitive type as string, int, float, boolean
                                },
                                ... // other fields
                    },
                    ... // other face matched of first face in image
                ],
                [
                    ... // list face matches of another face in image
                ],
            ],
                "collection_name2": ... // other result on collection_name2
        }
    },
    "errors": [
        {
            "code": string,
            "message": string,
            "detail": {
                "field": string, // optional, which parameter is invalid.
                ... // any other information that can be useful for client
            },
        },
        ... // other errors
    ]
}

Note:

  • The biggest faces were sorted on the top. We recommended using the first result in faces if the input image has multiple faces.

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.

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 codeerror codedescription
401access_denied_exceptionYou are not authorized to perform the action.
400invalid_parameter_exceptionInput parameter violates a constraint.
400request_time_too_skewedThe X-TV-Timestamp header is expired, need a newer one.
404image_not_found_exceptionThe image ID is not found in DB.
404request_not_found_exceptionThe request ID is not found when polling result by id
408request_timeout_exceptionRequest takes too long to process
429rate_limit_exceptionThe number of requests exceeded your throughput limit.
500internal_server_errorSome unexpected error occurs while processing the request

Sample Response

JSON
{
    "data": {
        "status": "success",
        "image": {
          "id": "a4facba3-334b-41fb-97e3-4766cb70ae29"
        },
        "faces": [
            [
                {
                    "id": "e8cd85a1-e1aa-4750-a0c9-1525fb524eed",
                    "image_id": "91b2c846-b701-4cc2-8061-1f243c50cc52",
                    "score": 1,
                    "metadata": [
                        {
                            "field": "app_id",
                            "value": 3333
                        },
                        {
                            "field": "national_id",
                            "value": 4444
                        }
                    ]
                },
                {
                    "id": "b05ed8b6-5d29-47a1-a934-f59f0197cea0",
                    "image_id": "ddb80011-c861-4904-a25f-c000cb969b61",
                    "score": 1,
                    "metadata": null
                },
                ...
            ]
        ],

        "request_id": "426bef5c-77ff-49e5-b0cd-b66651ac6427"
    }
}

Alert faces

The alert faces api takes an image with face and retrieves suspect faces similar to that out of a defined collection. Each matched face will be returned with a score of similarity (similar to compare faces service).

1. Request

Client should call this API:

methodURLcontent-type
POST/v1/alert_faces_syncapplication/json

Body:

JSON
{
    "image": {
        "id": string,
        "base64": string,
        "label": string,
        "metadata": string_json,
        "embedding": []float,
    },
}

Where

keytyperequireddescription
imageImageDatayesimage to index face. Should use image has the face

Which each image's parameters contains:

keytyperequireddescription
idstringnoID of image is returned from API Upload
base64stringnobase64 encoded text of image data
labelstringnolabel of the image as described at Label table
metadatastring_jsonnokey-value string, key should be string, value should be string, int, float, bool. Example "{\"id\":\"123456789\",\"type\":1}"
embedding[]floatnothe face's vectorized from API detect faces

Note:

  • If you use base64, label and metadata, omit parameter id.
  • If you use id (result id is returned from Upload Image API), omit parameter base64, label and metadata.
  • If you use embedding (result embedding is returned from Detect Faces API), omit parameter id, base64, label and metadata.
  • Priority order is id, (base64, label), embedding

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.

Sample Request

bash
curl -X POST \
https://tv-staging.trustingsocial.com/api/v1/alert_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 \
'
{
    "image": {
        "id": "a4facba3-334b-41fb-97e3-4766cb70ae29"
    }
}
'

2. Response

The response will be a JSON body with following format:

JSON
{
    "data": {
        "request_id": string,
        "status": string, // "success" or "failure"
        "faces": [   // support search multiple faces. Each array is result of each face
            [
                {
                    "name": string, // face name 1, 2, 3...
                    "score": float, // score similar between 2 faces
                    "created_at": date, // data time RFC3339 ex. 2006-01-02T15:04:05Z07:00
                    "applied_service": string, // kind of service that user applied
                    ... // other fields
                },
                ... // other face matched of first face in image
            ],
            [
                ... // list face matches of another face in image
            ],
        ],
        "history": [   // support history multiple faces. Each array is result of each face
            [
                {
                    "period": string, // time period as last_1day, last_7day, last_30day, last_180day
                    "num_suspect_faces": int, // number of matched faces in suspect DB
                    "num_member_suspect_faces": int, // number of members with face in suspect DB
                    "num_inquiry": int, // number of total inquiries made by all the member for this face
                    "num_member_inquiry": int, // Number of members which made the inquiry for this face in specific period
                },
                ... // other history for other time periods
            ],
            [
                ... // list history of another face in image
            ],
        ],
    },
    "errors": [
        {
            "code": string,
            "message": string,
            "detail": {
                "field": string, // optional, which parameter is invalid.
                ... // any other information that can be useful for client
            },
        },
        ... // other errors
    ]
}

Note:

  • The biggest faces were sorted on the top. We recommended using the first result in faces if the input image has multiple faces.

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.

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 codeerror codedescription
401access_denied_exceptionYou are not authorized to perform the action.
400invalid_parameter_exceptionInput parameter violates a constraint.
400request_time_too_skewedThe X-TV-Timestamp header is expired, need a newer one.
404image_not_found_exceptionThe image ID is not found in DB.
404request_not_found_exceptionThe request ID is not found when polling result by id
408request_timeout_exceptionRequest takes too long to process
429rate_limit_exceptionThe number of requests exceeded your throughput limit.
500internal_server_errorSome unexpected error occurs while processing the request

Sample Response

JSON
{
    "data": {
        "status": "success",
        "image": {
            "id": "2a5b80da-d093-4987-9711-9c7eb1b42a4d",
            "faces": [
                {
                    "bounding_box": {
                        "top":428,
                        "right":247,
                        "angle":0,
                        "bottom":521,
                        "left":168
                    },
                    "id": "30ae963d-d707-4528-a5ed-f3acc21f7dd7",
                    "landmarks": {
                        "left-mouth": {
                            "y":497.80352783203125,
                            "x":192.77993774414062
                        },
                        "left-eye": {
                            "y":460.55133056640625,
                            "x":189.2744140625
                        },
                        "nose": {
                            "y":483.4483947753906,
                            "x":207.6852569580078
                        },
                        "right-mouth": {
                            "y":497.8222961425781,
                            "x":222.74261474609375
                        },
                        "right-eye": {
                            "y":460.5907287597656,
                            "x":225.84567260742188
                        }
                    }
                }
            ]
        },
        "faces": [
            [
                {
                    "applied_service":null,
                    "created_at":"2021-06-19T18:23:28.453188+00:00",
                    "score":0.9999999999999221,
                    "name":"Face 1"
                }
            ]
        ],
        "history": [
            [
                {
                    "num_suspect_faces":0,
                    "num_inquiry":1,
                    "num_member_suspect_faces":0,
                    "num_member_inquiry":1,
                    "period":"last_1day"
                },
                {
                    "num_suspect_faces":0,
                    "num_inquiry":2,
                    "num_member_suspect_faces":0,
                    "num_member_inquiry":1,
                    "period":"last_7day"
                },
                {
                    "num_suspect_faces":0,
                    "num_inquiry":3,
                    "num_member_suspect_faces":0,
                    "num_member_inquiry":1,
                    "period":"last_30day"
                },
                {
                    "num_suspect_faces":1,
                    "num_inquiry":3,
                    "num_member_suspect_faces":1,
                    "num_member_inquiry":1,
                    "period":"last_180day"
                }
            ]
        ]
    }
}

Delete faces

The delete faces api takes a list of image ids to delete out of the index.

1. Request

Client should call this API:

methodURLcontent-type
POST/v1/delete_facesapplication/json

Body:

JSON
{
    "image_ids": []string,
    "collection": string,
}

Where

keytyperequireddescription
image_ids[]stringyesimage IDs in DB. Should use indexed image
collectionstringnoindex faces to this collection

Note: If not set collection, default collection will be used. Authentication mechanism is described in Authentication.

Sample Request

bash
curl -X POST \
https://tv-staging.trustingsocial.com/api/v1/delete_faces \
-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 \
'
{
    "image_ids": [
      "a4facba3-334b-41fb-97e3-4766cb70ae29",
      "7db00808-0416-45cf-a5cb-3b6dfbd7bb74"
    ]
}
'

2. Response

The response will be a JSON with following format:

JSON
{
    "data": {
        "request_id": string,
    },
    "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 of success, the HTTP status code will be 200, and the data will be an object containing following fields:

fieldtypedescription
request_idstringID of the request (UUID)

Sample Response Error

In case of error, the data will be empty, and server sends following HTTP status code and error information:

HTTP codeerror codedescription
401access_denied_exceptionYou are not authorized to perform the action.
400invalid_parameter_exceptionInput parameter violates a constraint.
400request_time_too_skewedThe X-TV-Timestamp header is expired, need a newer one.
404image_not_found_exceptionThe image ID is not found in DB.
408request_timeout_exceptionRequest takes too long to process
429rate_limit_exceptionThe number of requests exceeded your throughput limit.
500internal_server_errorSome unexpected error occurs while processing the request

Sample Response

JSON
{
    "data": {
        "request_id": "d4493ff5-e41f-4d10-a291-6a9727050b4c"
    }
}

Search Metadata

The search metadata api takes a metadata in json format to retrieve faces with embedded metadata similar to that out of a defined collection. Each matched record will be returned with a face, a score of similarity (similar to compare faces service) and metadata embedded with them.

1. Request

Client should call this API:

methodURLcontent-type
POST/v1/search_metadataapplication/json

Body:

JSON
{
    "metadata": dictionary,
    "collection": string,
    "max_results": int
}

Where

keytyperequireddescription
metadatadictionaryyeslist metadata key/value need search
collectionstringnosearch in face collection
max_resultsintnomaximum results. Default is 10

Note: If not set collection, default collection will be used.

Sample Request

bash
curl -X POST \
https://tv-staging.trustingsocial.com/api/v1/search_metadata \
-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 \
'
{
    "metadata":  {
        "national_id": "123456789"
    }
}
'

2. Response

The response will be a JSON body with following format:

JSON
{
    "data": {
        "request_id": string,
        "status": string, // "success" or "failure"
        "faces": [ // List faces have metadata matched with the search condition
                {
                    "id": string, // id of the face in image
                    "image_id": string, // id of original image
                    "metadata": // list of meta data information of this face
                        {
                            "field": string, // "application_id": "123", "national_id": 123, ...
                            ... // other fields
                        }
                },
                ... // other face matched of metadata
            ],
    },
    "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.

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 codeerror codedescription
401access_denied_exceptionYou are not authorized to perform the action.
400invalid_parameter_exceptionInput parameter violates a constraint.
400request_time_too_skewedThe X-TV-Timestamp header is expired, need a newer one.
404image_not_found_exceptionThe image ID is not found in DB.
404request_not_found_exceptionThe request ID is not found when polling result by id
408request_timeout_exceptionRequest takes too long to process
429rate_limit_exceptionThe number of requests exceeded your throughput limit.
500internal_server_errorSome unexpected error occurs while processing the request

Sample Response

JSON
{
    "data": {
        "faces": [
            {
                "id": "d7e3bc6c-6562-4a6d-b6a7-c85cf69c5fae",
                "image_id": "b35acc59-eefb-44fb-a6eb-ea02cec42cfc",
                "metadata": {
                    "app_id": "5555",
                    "national_id": "6666"
                }
            }
        ],
        "request_id": "59466df0-4815-49af-9652-622861b7a511",
        "status": "success"
    }
}

Update metadata

The upload metadata service allows one to add metadata to an image. It is also possible to override the existing metadata.

1. Request

Client should call this API:

methodURLcontent-type
PATCH/v1/images/{image_id}application/json

Body:

JSON
{
    "metadata": dictionary,
    "label": string,
    "override": bool,
}

Where

keytyperequireddescription
metadatadictionaryyeskey-value, key should be string, value should be string, int, float, bool
labelstringnolabel of the image as described at Label table
overrideboolnoflag to allow override old metadata or not

Sample Request

bash
curl -X PATCH \
https://tv-staging.trustingsocial.com/api/v1/images/a4facba3-334b-41fb-97e3-4766cb70ae29 \
-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 \
'
{
    "metadata":  {
        "national_id": "123456789"
    }
}
'

2. Response

The response will be a JSON with following format:

JSON
{
    "data": {
        "image_id": string, // ID of the uploaded image in DB
        "label": string, // Label of the uploaded image
        "metadata": dictionary, // Metadata of the uploaded image
    },
    "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 of success, the HTTP status code will be 200, and the data will be an object containing following fields:

fieldtypedescription
image_idstringID of the uploaded image (UUID)
labelstringlatest label of the image
metadatadictionarylatest metadata of the image

Sample Response Error

In case of error, the data will be empty, and server sends following HTTP status code and error information:

HTTP codeerror codedescription
401access_denied_exceptionYou are not authorized to perform the action.
400invalid_parameter_exceptionInput parameter violates a constraint.
404image_not_found_exceptionThe image ID is not found in DB.
408request_timeout_exceptionRequest takes too long to process
429rate_limit_exceptionThe number of requests exceeded your throughput limit.
500internal_server_errorSome unexpected error occurs while processing the request

Sample Response

JSON
{
    "data": {
        "image_id": "b35acc59-eefb-44fb-a6eb-ea02cec42cfc",
        "label": "portrait",
        "metadata": {
            "app_id": "5555",
            "national_id": "6666"
        }
    }
}

Delete files

The delete files api takes a list of image ids to delete out of the storage. The purpose of this activity is client can delete immediately uploaded files.

1. Request

Client should call this API:

methodURLcontent-type
POST/v1/delete_filesapplication/json

With following form-data fields:

fieldtyperequireddescription
file_ids[]stringrequiredarray of file IDs in DB

With file_ids parameter contains max 100 ids

Authentication mechanism is described in Authentication.

Sample Request

bash
curl -X POST \
https://tv-staging.trustingsocial.com/api/v1/delete_files \
-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 \
'
{
    "file_ids":  [
      "a4facba3-334b-41fb-97e3-4766cb70ae29",
      "3b4bf7b6-088b-4931-9279-9259f5c34fe3"
    ]
}
'

2. Response

The response will be a JSON with following format:

JSON
{
    "data": {
        "status": string, // "success" or "failure"
    },
    "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.

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 codeerror codedescription
401access_denied_exceptionYou are not authorized to perform the action.
405not_allow_delete_exceptionNot allow to delete file
408request_timeout_exceptionRequest takes too long to process
429rate_limit_exceptionThe number of requests exceeded your throughput limit.
500internal_server_errorSome unexpected error occurs while processing the request

Sample Response

JSON
{
    "data": {
        "status": "success"
    }
}

Get result of the request

1. Request

Client should call this API:

methodURLcontent-type
GET/v1/requests_by_req_id/{request_id}application/json

Where request_id is the ID of the request returned in previous API call.

Sample Request

bash
curl -X GET \
https://tv-staging.trustingsocial.com/api/v1/requests_by_req_id/a4facba3-334b-41fb-97e3-4766cb70ae29 \
-H 'Authorization: TV <YOUR ACCESS KEY>:<CREATED SIGNATURE>' \
-H 'X-TV-Timestamp: 2019-04-21T18:00:15+07:00' \
-H 'Content-Type: application/json'

2. Response

Service nameResponse
Read ID card infoCheck the response section read_id_card_info
Verify face livenessCheck the response section verify_face_liveness
Verify face video livenessCheck the response section verify_face_video_liveness
Verify portrait sanityCheck the response section verify_portrait_sanity
Compare facesCheck the response section compare_faces
Search facesCheck the response section search_faces
Verify ID cardCheck the response section verify_id_card_sanity
ID Card tamperingCheck the response section detect_id_card_tampering
Detect ID cardsCheck the response section detect_id_cards

Sample Response

JSON
{
    "data": {
        "details": null,
        "images": [
            {
                "id": "0e33129a-c9ec-4e22-bf53-78d496bb1f37",
                "is_live": true,
                "score": 0.981541368665434
            },
            {
                "id": "9687e2c9-4f99-46e8-a4d9-4469d61de829",
                "is_live": true,
                "score": 0.9879801868228469
            },
            {
                "id": "007b943c-eda3-4b08-8c80-da258cb69eac",
                "is_live": true,
                "score": 0.9843504686937438
            },
            {
                "id": "d98d5b5c-30e0-43c2-b812-7d53f0fc585d",
                "is_live": true,
                "score": 0.9493469735404098
            },
            {
                "id": "010b5aa5-ef2a-47fe-937d-b5d10dfad443",
                "is_live": true,
                "score": 0.9687573370988268
            },
            {
                "id": "845c3a3b-623a-4de0-8f13-e43115239e5b",
                "is_live": true,
                "score": 0.9464235386207961
            }
        ],
        "is_live": true,
        "request_id": "93029850-924c-465a-baa6-27d843cbb1ba",
        "service": "verify_face_liveness",
        "score": 0.9999999862517992,
        "status": "success",
        "videos": [
            {
                "is_live": true,
                "score": 1
            }
        ]
    }
}

Get requests by x-request-id

1. Request

Client should call this API:

methodURLcontent-type
GET/v1/requests_by_x_req_id/:x_request_id?max_results={max_results}application/json

With following parameters:

fieldtyperequireddescription
x_request_idstringyesget requests that share this x-request-id
max_resultsintnomax number of results

2. Response

The response will be a JSON with following format:

json
{
    "data": {
        "file_ids": [ // input file ids of all requests below, no duplicated id
            {
                "id": string,
                "label": string,
                "gesture": string, // optional
            }
        ],
        "compare_faces": [ // service name
            {
                "data": {
                    "request_id": string, // request_id
                    "x_request_id": string,
                    "access_key_id": string,
                    "file_ids": [ // input file ids, optional
                        {
                            "id": string,
                            "label": string,
                            "gesture": string, // optional
                        }
                    ],
                    ... // other request field
                }
            },
            ... // other request
        ],
        ... // other service
    }
    "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.

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 codeerror codedescription
401access_denied_exceptionYou are not authorized to perform the action.
400invalid_parameter_exceptionInput parameter violates a constraint.
500internal_server_errorSome unexpected error occurs while processing the request

Detect ID cards

1. Request

Client should call this API:

methodURLcontent-type
POST/v1/detect_id_cards_syncapplication/json

Body:

JSON
{
    "card_type": string,
    "image": {
        "id": string,
        "base64": string,
        "label": string,
        "metadata": string_json,
    }
}

Where

keytyperequireddescription
card_typestringyestype of identity card, described at Card type table
imageImageDatayesimage of the identity card's front side

Which each image's parameters contains:

keytyperequireddescription
idstringnoID of image is returned from API Upload
base64stringnobase64 encoded text of image data
labelstringnolabel of the image as described at Label table
metadatastring_jsonnokey-value string, key should be string, value should be string, int, float, bool. Example "{\"id\":\"123456789\",\"type\":1}"

Note:

  • If you use base64, label and metadata, omit parameter id.
  • If you use 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.

Sample Request

bash
curl -X POST \
https://tv-staging.trustingsocial.com/api/v1/detect_id_cards_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 \
'
{
    "card_type": "vn.national_id",
    "image":  {
        "id": "a4facba3-334b-41fb-97e3-4766cb70ae29"
    }
}
'

2. Response

The response will be a JSON with following format:

JSON
{
    "data": {
        "request_id": string,
        "status": string, // "success" or "failure"
        "image": {
            "id": string,
            "cards": [
                {
                    "transformed_image_id": string, // optional, in case the card is transformed (setting `enable_create_image` is True)
                    "card_label": string, // see below
                    "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 },
                    },
                },
                ... // other cards in the image
            ],
        },
        "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
    ]
}

Label and type of identity card, described at Card type table :

card_labeldescription
vn.cmnd_old.frontThe front side of Vietnam national ID old version (Chứng minh nhân dân cũ)
vn.cmnd_old.backThe back side of Vietnam national ID old version (Chứng minh nhân dân cũ)
vn.cmnd_new.frontThe front side of Vietnam national ID new version (Chứng minh nhân dân mới)
vn.cmnd_new.backThe back side of Vietnam national ID new version (Chứng minh nhân dân mới)
vn.cccd.frontThe front side of Vietnam national ID latest version (Căn cước công dân)
vn.cccd.backThe back side of Vietnam national ID latest version (Căn cước công dân)
vn.cccd_new.frontThe front side of Vietnam national ID latest version (Căn cước công dân gắn chip)
vn.cccd_new.backThe back side of Vietnam national ID latest version (Căn cước công dân gắn chip)
vn.passport.frontMain page of Vietnam passport
vn.mid.frontFront side of Vietnam military ID card
vn.mid.backBack side of Vietnam military ID card
in.aadhaar.frontFront side of India Aadhaar card
in.aadhaar.backBack side of India Aadhaar card
in.aadhaar_letter.backBack side of India Aadhaar letter
in.voter.frontFront side of India Voter card
in.voter.backBack side of India Voter card
in.pan.frontFront side of India PAN card
in.pan.backBack side of India PAN card
in.passport.backBack side of India passport
in.dl.frontFront side of India driving license
ph.ump.frontThe front side of Philippines UMP
ph.tin.frontThe front side of Philippines TIN
ph.dl.frontThe front side of Philippines DL
ph.sss.frontThe front side of Philippines SSS
ph.nid.frontThe front side of Philippines NID
ph.passport.frontThe front side of Philippines passport
ph.postal.frontThe front side of Philippines postal
ph.philhealth.frontThe front side of Philippines philhealth
ph.prc.frontThe front side of Philippines PRC
ph.loyalty.frontThe front side of Philippines loyalty

The data.status is either "success" or "failure" depending on whether the request has been successfully processed or not.

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 codeerror codedescription
401access_denied_exceptionYou are not authorized to perform the action.
400invalid_parameter_exceptionInput parameter violates a constraint.
400request_time_too_skewedThe X-TV-Timestamp header is expired, need a newer one.
404image_not_found_exceptionThe image ID is not found in DB.
404request_not_found_exceptionThe request ID is not found when polling result by id
408request_timeout_exceptionRequest takes too long to process
429rate_limit_exceptionThe number of requests exceeded your throughput limit.
500internal_server_errorSome unexpected error occurs while processing the request

Sample Response

JSON
{
  "data": {
    "request_id": "f77bf948-fce3-48f3-b61c-396e4cd9a89b",
    "status": "success",
    "image": {
      "id": "854322f0-eb49-4bd6-b870-050fcc088d10",
      "cards": [
        {
          "card_box": {
            "bottom_left": {
              "x": 102.62150720786303,
              "y": 679.5154545297846
            },
            "bottom_right": {
              "x": 996.863339483738,
              "y": 661.6368409626185
            },
            "top_left": {
              "x": 90.52290163561702,
              "y": 110.761657032324
            },
            "top_right": {
              "x": 981.4022462964058,
              "y": 101.39770825190935
            }
          },
          "card_label": "vn.cccd_new.front",
          "transformed_image_id": ""
        }
      ]
    }
  }
}

Create temporary credential

The API create a temporary credential to create temporary access key and secret key with the same permission of long term access key and secret key.

1. Request

Client should call this API:

methodURLcontent-type
POST/v1/temporary_credentialapplication/json

Body:

JSON
{
    "duration_seconds": int,
}

Where

keytyperequireddescription
duration_secondsintnolive time of a credential. Default is 15 minutes
servicesjsonnoservices permission for temporary credentials. Default is the same permission as the origin

Authentication mechanism is described in Authentication.

Sample Request

bash
curl -X POST \
https://tv-staging.trustingsocial.com/api/v1/temporary_credential \
-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 \
'
{
    "duration_seconds": 1500,
    "services": {
      "verify_face_liveness": true,
      "read_id_card_info": true
    }
}
'

2. Response

The response will be a JSON with following format:

JSON
{
    "data": {
        "access_key": string,
        "secret": string,
        "expire_at": string,
    },
    "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 of success, the HTTP status code will be 200, and the data will be an object containing following fields:

fieldtypedescription
access_keystringAPI key
secretstringAPI secret
expire_atstringExpiration timestamp

Sample Response Error

In case of error, the data will be empty, and server sends following HTTP status code and error information:

HTTP codeerror codedescription
400invalid_parameter_exceptionInput parameter violates a constraint.
400request_time_too_skewedThe X-TV-Timestamp header is expired, need a newer one.
408request_timeout_exceptionRequest takes too long to process
429rate_limit_exceptionThe number of requests exceeded your throughput limit.
500internal_server_errorSome unexpected error occurs while processing the request

Sample Response

JSON
{
    "data": {
        "access_key": "ba7a7b71-601e-4771-a53c-a85b5d5d3209",
        "expire_at": "2022-10-18T09:29:05.590354092Z",
        "secret": "dLfV0PhtHaCaveLIE7C0rZsB6EJvY4cn"
    }
}

Full eKYC

The API eKYC will do all steps as Sanity, ID Tampering, OCR, Face Matching, Liveness, Face Retrieval check to a API. The settings at the backend control the services

1. Request

Client should call this API:

methodURLcontent-type
POST/v1/ekycapplication/json

Body:

JSON
{
    "card_type": string,
    "image1": {
        "id": string,
        "base64": string,
        "label": string,
        "metadata": string_json,
    },
    "image2": {
        "id": string,
        "base64": string,
        "label": string,
        "metadata": string_json,
    },
    "selfies": [
        {
            "id": string,
            "base64": string,
            "label": string,
            "metadata": string_json,
        },
        ...
    ]
}

Where

keytyperequireddescription
card_typestringyestype of identity card, described at Card type table
image1ImageDatayesimage of the identity card's front side
image2ImageDatanoimage of the identity card's back side
selfies[]ImageDatayeslist selfie images of customer. Max 3 images

Which each image's parameters contains:

keytyperequireddescription
idstringnoID of image is returned from API Upload
base64stringnobase64 encoded text of image data
labelstringnolabel of the image as described at Label table
metadatastring_jsonnokey-value string, key should be string, value should be string, int, float, bool. Example "{\"id\":\"123456789\",\"type\":1}"

Note:

  • If you use base64, label and metadata, omit parameter id.
  • If you use 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.

Sample Request

bash
curl -X POST \
https://tv-staging.trustingsocial.com/api/v1/ekyc \
-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"
    },
    "selfies": [
      {
        "id": "cfc7b8d5-f2e2-437b-80e5-d600dfad26e2"
      }
    ]
}
'

2. Response

The response will be a JSON with following format:

JSON
{
    "data": {
        "status": string, // "success" or "failure"
        "transaction_id": string, // optional
        "request_id": string,
        "card_information": [ // merged and normalized information from QR and OCR of both image1 and image2
            {
                "field": string, // field name ("identity_number", "full_name", "birth_date")
                "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
        ],
        "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
        ],
        "liveness_check": {
            "is_live": bool, // the face is live or not
            "score": float // how likely that the face is live (0-1)
        },
        "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
    ]
}

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 codedescription
image_has_no_facesthe input image has no faces
incorrect_card_typethe input image is not same type with selected card
nocard_or_multicard_imagethe input image is no card or multicard detected
image_too_blurthe input image is too blur
image_too_darkthe input image is too dark
image_too_brightthe input image is too bright (glare)
image_has_holethe input image has hole
image_has_cutthe input image has cut
image_has_hole_and_cutthe input image has hole and cut
bad_quality_card_imagethe input image is bad quality
not_qualifiedthe input image is bad quality
not_white_backgroundthe image was not taken with a white background
rightthe face is turned right
leftthe face is turned left
open_eye,closed_eyethe face has eye(s) closed
closed_eye,open_eyethe face has eye(s) closed
open_eye,sunglassesthe face has sunglasses
sunglasses,open_eyethe face has sunglasses
closed_eye,closed_eyethe face has eye(s) closed
closed_eye,sunglassesthe face has sunglasses
sunglasses,closed_eyethe face has sunglasses
sunglasses,sunglassesthe face has sunglasses

error.detail field will tell you what type of error from sanity

field namedescription
sanitytype of sanity of image as portrait or id_card

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 codeerror codedescription
401access_denied_exceptionYou are not authorized to perform the action.
400invalid_parameter_exceptionInput parameter violates a constraint.
400request_time_too_skewedThe X-TV-Timestamp header is expired, need a newer one.
404image_not_found_exceptionThe image ID is not found in DB.
404request_not_found_exceptionThe request ID is not found when polling result by id
408request_timeout_exceptionRequest takes too long to process
429rate_limit_exceptionThe number of requests exceeded your throughput limit.
500internal_server_errorSome unexpected error occurs while processing the request

Sample Response

JSON
{
    "data": {
        "status": "success",
        "request_id": "5751bbbd-c832-4a7b-9971-489ecce4c0ac",
        "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"
          },
          ...
        ],
        "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
            }
        ],
        "liveness_check": {
            "is_live": true,
            "score": 0.9999999862517992
        }
    }
}

Request face authentication registration

1. Request

Client should call this API:

methodURLcontent-type
POST/v1/face_auth_registerapplication/json

Body:

JSON
{
    "cus_user_id": string,
    "faces": [
        {
            "id": string,
            "base64": string,
            "label": string,
            "metadata": string_json,
        }
    ],
    "gesture_faces":[
        {
            "gesture": string,
            "images": [
                {
                        "id": string,
                        "base64": string,
                        "label": string,
                        "metadata": string_json,
                    },
                    {
                        "id": string,
                        "base64": string,
                        "label": string,
                        "metadata": string_json,
                    }
            ],
        }
    ],
    "videos": [
        {
            "id": string,
            "metadata": string_json,
            "frames": [
                {
                    "base64": string,
                    "label": string,
                    "index": int,
                    "metadata": string_json,
                },
                {
                    "base64": string,
                    "label": string,
                    "index": int,
                    "metadata": string_json,
                },
                // other frames
            ],
        },
        {
            "id": string,
            "metadata": string_json,
            "frames": [
                {
                    "base64": string,
                    "label": string,
                    "index": int,
                    "metadata": string_json,
                },
                {
                    "base64": string,
                    "label": string,
                    "index": int,
                    "metadata": string_json,
                },
                // other frames
            ],
        },
        ... // other videos
    ],
    "gesture_videos": [
        {
            "gesture": string,
            "videos": [
                {
                    "id": string,
                    "metadata": string_json,
                    "frames": [
                        {
                            "base64": string,
                            "label": string,
                            "index": int,
                            "metadata": string_json,
                        },
                        {
                            "base64": string,
                            "label": string,
                            "index": int,
                            "metadata": string_json,
                        },
                        // other frames
                    ],
                },
                ... // other videos
            ]
        },
        ... // other gesture videos
    ],
    "face_in_id_card": {
        "id": string,
        "base64": string,
        "label": string,
        "metadata": string_json,
    },
    "device_id": string,
    "app_id": string,
    "lat": float,
    "lng": float,
    "face_type": string,
    "selfie_type": string,
    "history_return_count": int,
    "history_return_status": string,
    "metadata": json_object
}

Where

keytyperequireddescriptionmax length
cus_user_idstringyesuser id of customer256
faces[]imagenoimages of the selfie50
gesture_faces[]gesture_imagenoarray of gestures contain images50
videos[]videonoarray of videos selfie50
gesture_videos[]gesture_videonoarray of videos gesture50
face_in_id_cardimagenoimage of the face in id_card
device_idstringnodevice id of user256
app_idstringnoapp id of customer128
latfloatnolatitude of device
lngfloatnolongitude of device
face_typestringnotype of face input (selfie, id_card)
selfie_typestringnospecify the characteristic of authentication type eg. Light, Standard, Edge, Advanced, NFC64
history_return_countintnonumber of history registration records to return
history_return_statusstringnostatus of history registration records to return (success, failure or all)
metadatajson_objectnoany key-value metadata to store with this customer

Which each image's parameters contains:

keytyperequireddescription
idstringnoID of image is returned from API Upload
base64stringnobase64 encoded text of image data
labelstringnolabel of the image as described at Label table
metadatastring_jsonnokey-value string, key should be string, value should be string, int, float, bool. Example "{\"id\":\"123456789\",\"type\":1}"

Which each gesture_image's parameters contains:

keytyperequireddescription
gesturestringyesspecify a gesture value as bellow table. Example left, right, up or down
images[]imageyesan array of images for each gesture

Which gesture parameter contains value:

gesturesdescription
leftthe face turns left
rightthe face turns left
upthe face up
downthe face down

Which each video's parameters contains:

keytyperequireddescription
idstringnoID of video is returned from API Upload
metadatastring_jsonnokey-value string, key should be string, value should be string, int, float, bool. Example "{\"id\":\"123456789\",\"type\":1}"
frames[]FrameDatanolist of video frames to be uploaded

Which FrameData's parameters contains:

keytyperequireddescription
base64stringnobase64 encoded text of image data
labelstringnolabel of the image as described at Label table
indexintnothe index of this frame in the video
metadatastring_jsonnokey-value string, key should be string, value should be string, int, float, bool. Example "{\"id\":\"123456789\",\"type\":1}"

Which each gesture_video's parameters contains:

keytyperequireddescription
gesturestringyesspecify a gesture value as bellow table. Example left, right, up or down
videos[]videoyesan array of videos for each gesture

Which selfie_type parameter is defined as below table values

selfie_typedescription
id_cardPortrait image in Chip NFC of CCCD

Note:

  • The parameter face_in_id_card or faces is required. you have to specify at least one
  • For parameter type image, if you use id (result id is returned from Upload Image API), omit parameter base64, label and metadata. If you use base64, label and metadata, omit parameter id.
  • For parameter type video, if you use id (result id is returned from Upload File API), omit parameter frames, metadata. If you use frames, metadata, omit parameter id.
  • If parameter face_type is not specified, the default value is selfie.
  • If you want to register face from ID card (e.g. face extracted while reading NFC of Citizen ID Card), you have to either:
    • Pass the face to faces param and specify face_type and selfie_type as id_card.
    • Or pass the face to face_in_id_card (no need to specify face_type or selfie_type).
  • To register both face from ID card and selfie, please pass the selfie face to faces param and the face from ID card to face_in_id_card param.

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.

Sample Request

bash
curl -X POST \
https://tv-staging.trustingsocial.com/api/v1/face_auth_register \
-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 \
'
{
    "cus_user_id": "3b4bf7b6-088b-4931-9279-9259f5c34fe3",
    "faces": [
        {
            "id": "a4facba3-334b-41fb-97e3-4766cb70ae29"
        },
        {
            "id": "c5a2a405-f152-4248-b746-3af76b241ef7"
        },
        {
            "id": "5d0345f7-da7c-44e8-bd6c-a8c08c806227"
        }
    ],
    "gesture_faces": [
        {
            "gesture": "left",
            "images": [
                {
                    "id": "d849a3ce-d209-4605-99a7-3d369234fd5e"
                }
            ]
        },
        {
            "gesture": "up",
            "images": [
                {
                    "id": "551fc06a-14fd-44dc-8838-abe895007c36"
                }
            ]
        },
        {
            "gesture": "right",
            "images": [
                {
                    "id": "536d2457-bfc0-4249-85f2-8c4053bdec58"
                }
            ]
        }
    ],
    "videos": [
        {
            "id": "61801fcd-b109-49f7-b871-ae82c2a666cc",
        },
        {
            "id": "1f93d229-7f1c-44f9-a85b-1be4c2d4be41",
        }
    ],
    "face_type": "selfie",
    "metadata": {
        "key1": {
          "key11": "value11",
          "key12": "value12"
        },
        "key2": "value2"
    }
}
'

2. Response

The response will be a JSON with following format:

JSON
{
    "data": {
        "status": string, // "success" or "failure"
        "request_id": string, // return request id to the client and can use request-id to check logs.
        "user_metadata": json_object, // return user metadata
        "register_id": string, // id of this registration request
        "histories": [
            {
                "id": string, // id of this history
                "client_id": string, // client id
                "cus_user_id": string, // user id
                "face_auth_id": string, // id of selfie image containing user's face
                "id_card_face_id": string, // id of id card image containing user's face
                "live_face_id": string, // id of input image for this registration request
                "device_id": string, // device id input for this registration request
                "app_id": string, // app id input for this registration request
                "latitude": float, // latitude input for this registration request
                "longitude": float, // longitude input for this registration request
                "created_at": string, // time of this registration request
                "auth_action": string, // "register"
                "status": string, // "success" or "failure"
                "result": string, // detail result of this registration request
                "metadata": json_object, // metadata input for this registration request
                "face_type": string, // type of face input for this registration request ("selfie", "id_card")
            },
            ... // other history
        ]
    },
    "errors": [
        {
            "code": string,
            "message": string,
            "detail": {
                "field": string, // optional, which parameter is invalid.
                ... // any other information that can be useful for client
            },
        },
        ... // other errors
    ]
}

The expiry_date of selfie face will be returned in user_metadata field as expiry_date_face in RFC3339 format.

In case the request processing has been finished successfully, 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 codedescription
face_auth_user_deactivatedthe user is deactivated

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 codeerror codedescription
401access_denied_exceptionYou are not authorized to perform the action.
400invalid_parameter_exceptionInput parameter violates a constraint.
400request_time_too_skewedThe X-TV-Timestamp header is expired, need a newer one.
400incorrect_number_of_facesSelfie or original image have more than 1 faces.
404image_not_found_exceptionThe image ID is not found in DB.
404request_not_found_exceptionThe request ID is not found when polling result by id
408request_timeout_exceptionRequest takes too long to process
429rate_limit_exceptionThe number of requests exceeded your throughput limit.
500internal_server_errorSome unexpected error occurs while processing the request

Sample Response

JSON
{
    "data": {
        "status": "success",
        "request_id": "cfc7b8d5-f2e2-437b-80e5-d600dfad26e2",
        "user_metadata": {
            "key1": "value1",
            "key2": 2,
            "expiry_date_face": "2023-12-27T03:33:06.307977Z",
        },
        "register_id": "d4f99f9b-4862-437f-a9c9-608e050d06c6",
        "histories": [
            {
                "id": "f1ca6795-cbd4-4eec-821f-b4ac646db627",
                "client_id": "0ef0f7e9-7f2f-4767-84b8-f76da7701c46",
                "cus_user_id": "3b4bf7b6-088b-4931-9279-9259f5c34fe3",
                "face_auth_id": "",
                "id_card_face_id": "4f959f4a-f5de-4b50-8724-224e709d06c2",
                "live_face_id": "009161c9-9c89-4573-8119-8f513de4449c",
                "created_at": "2023-12-27T03:33:06.307977Z",
                "auth_action": "register",
                "status": "success",
                "result": "",
                "face_type": "selfie"
            },
            {
                "id": "8c23af95-aaa0-4448-bfba-68acce31236e",
                "client_id": "0ef0f7e9-7f2f-4767-84b8-f76da7701c46",
                "cus_user_id": "3b4bf7b6-088b-4931-9279-9259f5c34fe3",
                "face_auth_id": "",
                "id_card_face_id": "4f959f4a-f5de-4b50-8724-224e709d06c2",
                "live_face_id": "009161c9-9c89-4573-8119-8f513de4449c",
                "created_at": "2023-12-21T07:24:19.829484Z",
                "auth_action": "register",
                "status": "failure",
                "result": "image is not liveness",
                "face_type": "id_card"
            }
        ]
    }
}

Request face authentication

1. Request

Client should call this API:

methodURLcontent-type
POST/v1/face_authapplication/json

Body:

JSON
{
    "cus_user_id": string,
    "client_transaction_id": string,
    "faces": [
        {
            "id": string,
            "base64": string,
            "label": string,
            "metadata": string_json,
        }
    ],
    "gesture_faces":[
        {
            "gesture": string,
            "images": [
                {
                        "id": string,
                        "base64": string,
                        "label": string,
                        "metadata": string_json,
                    },
                    {
                        "id": string,
                        "base64": string,
                        "label": string,
                        "metadata": string_json,
                    }
            ],
        }
    ],
    "videos": [
        {
            "id": string,
            "metadata": string_json,
            "frames": [
                {
                    "base64": string,
                    "label": string,
                    "index": int,
                    "metadata": string_json,
                },
                {
                    "base64": string,
                    "label": string,
                    "index": int,
                    "metadata": string_json,
                },
                // other frames
            ],
        },
        {
            "id": string,
            "metadata": string_json,
            "frames": [
                {
                    "base64": string,
                    "label": string,
                    "index": int,
                    "metadata": string_json,
                },
                {
                    "base64": string,
                    "label": string,
                    "index": int,
                    "metadata": string_json,
                },
                // other frames
            ],
        },
        ...
    ],
    "gesture_videos": [
        {
            "gesture": string,
            "videos": [
                {
                    "id": string,
                    "metadata": string_json,
                    "frames": [
                        {
                            "base64": string,
                            "label": string,
                            "index": int,
                            "metadata": string_json,
                        },
                        {
                            "base64": string,
                            "label": string,
                            "index": int,
                            "metadata": string_json,
                        },
                        // other frames
                    ],
                },
                ... // other videos
            ]
        },
        ... // other gesture videos
    ],
    "device_id": string,
    "app_id": string,
    "lat": float,
    "lng": float,
    "auth_type": string,
    "selfie_type": string,
    "history_return_count": int,
    "history_return_status": string,
    "metadata": json_object
}

Where

keytyperequireddescriptionmax length
cus_user_idstringyesuser id of customer256
faces[]imagenoimages of the selfie50
gesture_faces[]gesture_imagenoarray of gestures contain images50
videos[]videonoarray of videos selfie50
gesture_videos[]gesture_videonoarray of videos gesture50
device_idstringnodevice id of user256
app_idstringnoapp id of customer128
latfloatnolatitude of device
lngfloatnolongitude of device
auth_typestringnospecify different authentication type (or different use-cases)64
client_transaction_idstringnoclient transaction ID
selfie_typestringnospecify the characteristic of authentication type eg. Light, Standard, Edge, Advanced64
history_return_countintnonumber of history authenticate records to return
history_return_statusstringnostatus of history authenticate records to return (success, failure or all)
metadatajson_objectnoany key-value metadata to store with this login time

Which each image's parameters contains:

keytyperequireddescription
idstringnoID of image is returned from API Upload
base64stringnobase64 encoded text of image data
labelstringnolabel of the image as described at Label table
metadatastring_jsonnokey-value string, key should be string, value should be string, int, float, bool. Example "{\"id\":\"123456789\",\"type\":1}"

Which each gesture_image's parameters contains:

keytyperequireddescription
gesturestringyesspecify a gesture value as bellow table. Example left, right, up or down
images[]imageyesan array of images for each gesture

Which gesture parameter contains value:

gesturesdescription
leftthe face turns left
rightthe face turns left
upthe face up
downthe face down

Which each video's parameters contains:

keytyperequireddescription
idstringnoID of video is returned from API Upload
metadatastring_jsonnokey-value string, key should be string, value should be string, int, float, bool. Example "{\"id\":\"123456789\",\"type\":1}"
frames[]FrameDatanolist of video frames to be uploaded

Which FrameData's parameters contains:

keytyperequireddescription
base64stringnobase64 encoded text of image data
labelstringnolabel of the image as described at Label table
indexintnothe index of this frame in the video
metadatastring_jsonnokey-value string, key should be string, value should be string, int, float, bool. Example "{\"id\":\"123456789\",\"type\":1}"

Which each gesture_video's parameters contains:

keytyperequireddescription
gesturestringyesspecify a gesture value as bellow table. Example left, right, up or down
videos[]videoyesan array of videos for each gesture

Define flow based on parameters

The auth_type parameter is defined for each use-case differently

auth_typedescription
reset_passwordAuthenticate to reset password flow
loginUse face to replace text password
paymentAuthenticate payment
transferAuthenticate transfer
transfer_type_AAuthenticate transfer type A
transfer_type_BAuthenticate transfer type B
transfer_type_CAuthenticate transfer type C
transfer_type_DAuthenticate transfer type D
...You can define any authentication type based on your business

The selfie_type parameter is defined as below table values

selfie_typedescription
lightLight Authen
passiveStandard Authen
activeAdvanced Authen use active liveness (gestures)
flashAdvanced Authen uses full flash liveness
flash_8Edge Authen uses flash liveness with 8 frames
flash_16Edge Authen uses flash liveness with 16 frames
flash_32Advanced Authen uses flash liveness with 32 frames
flash_edgeEdge Authen uses flash liveness with minimum time
flash_advancedAdvanced Authen uses full flash liveness

Note:

  • The parameter face or faces is required. you have to specify at least one
  • For parameter type image, if you use id (result id is returned from Upload Image API), omit parameter base64, label and metadata. If you use base64, label and metadata, omit parameter id.
  • For parameter type video, if you use id (result id is returned from Upload File API), omit parameter frames, metadata. If you use frames, metadata, omit parameter id.

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.

Sample Request

bash
curl -X POST \
https://tv-staging.trustingsocial.com/api/v1/face_auth \
-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 \
'
{
    "cus_user_id": "3b4bf7b6-088b-4931-9279-9259f5c34fe3",
    "faces": [
        {
            "id": "a4facba3-334b-41fb-97e3-4766cb70ae29"
        },
        {
            "id": "c5a2a405-f152-4248-b746-3af76b241ef7"
        },
        {
            "id": "5d0345f7-da7c-44e8-bd6c-a8c08c806227"
        }
    ],
    "gesture_faces": [
        {
            "gesture": "left",
            "images": [
                {
                    "id": "d849a3ce-d209-4605-99a7-3d369234fd5e"
                }
            ]
        },
        {
            "gesture": "up",
            "images": [
                {
                    "id": "551fc06a-14fd-44dc-8838-abe895007c36"
                }
            ]
        },
        {
            "gesture": "right",
            "images": [
                {
                    "id": "536d2457-bfc0-4249-85f2-8c4053bdec58"
                }
            ]
        }
    ],
    "videos": [
        {
            "id": "61801fcd-b109-49f7-b871-ae82c2a666cc",
        },
        {
            "id": "1f93d229-7f1c-44f9-a85b-1be4c2d4be41",
        }
    ],
    "metadata": {
        "key1": {
          "key11": "value11",
          "key12": "value12"
        },
        "key2": "value2"
    }
}
'

2. Response

The response will be a JSON with following format:

JSON
{
    "data": {
        "status": string, // "success" or "failure"
        "auth_check": {
            "score": float, // how likely that face1 and face2 are matched (0-1)
            "result": string // "matched", "unmatched"
        },
        "request_id": string, // return request id to the client and can use request-id to check logs.
        "user_metadata": json_object, // return user metadata
        "validate_faces_result": {
            "sanity_verdict": string, // portrait_sanity check result, if field not exist or value is "", it means portrait_sanity check is not performed
            "is_live": bool, // liveness check result, if field not exist or value is null, it means liveness check is not performed
            "sanity_check: {...}, // full sanity check response
            "liveness_check: {...} // full liveness check response
        },
        "auth_id": string, // id of this authentication request
        "histories": [
            {
                "id": string, // id of this history
                "client_id": string, // client id
                "cus_user_id": string, // user id
                "face_auth_id": string, // id of selfie image containing user's face
                "id_card_face_id": string, // id of id card image containing user's face
                "live_face_id": string, // id of input image for this login request
                "device_id": string, // device id input for this login request
                "app_id": string, // app id input for this login request
                "latitude": float, // latitude input for this login request
                "longitude": float, // longitude input for this login request
                "created_at": string, // time of this login request
                "auth_action": string, // "login"
                "status": string, // "success" or "failure"
                "result": string, // detail result of this login request
                "metadata": json_object, // metadata input for this login request
                "face_type": string, // type of face used to compare against the input face to authenticate ("selfie", "id_card")
            },
            ... // other history
        ]
    },
    "errors": [
        {
            "code": string,
            "message": string,
            "detail": {
                "field": string, // optional, which parameter is invalid.
                ... // any other information that can be useful for client
            },
        },
        ... // other errors
    ]
}

The expiry_date of selfie face will be returned in user_metadata field as expiry_date_face in RFC3339 format.

In case the request processing has been finished successfully, 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.

fieldsdescription
auth_checkhave result (matched/unmatched) and score

If the data.status is "failure", the "errors" field will tell you why it failed.

error codedescription
image_too_blurthe input image is too blur
image_too_darkthe input image is too dark
image_too_brightthe input image is too bright (glare)
image_has_no_facesthe input image has no faces
image_non_livenessthe input image is not liveness
face_auth_user_deactivatedthe user is deactivated
face_auth_user_unregisteredthe user is unregistered from face_auth service

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 codeerror codedescription
401access_denied_exceptionYou are not authorized to perform the action.
400invalid_parameter_exceptionInput parameter violates a constraint.
400request_time_too_skewedThe X-TV-Timestamp header is expired, need a newer one.
400incorrect_number_of_facesSelfie or original image have more than 1 faces.
404image_not_found_exceptionThe image ID is not found in DB.
404request_not_found_exceptionThe request ID is not found when polling result by id
404face_auth_user_not_found_exceptionThe user of face_auth service not found.
408request_timeout_exceptionRequest takes too long to process
429rate_limit_exceptionThe number of requests exceeded your throughput limit.
500internal_server_errorSome unexpected error occurs while processing the request

Sample Response

JSON
{
    "data": {
        "status": "success",
        "auth_check": {
            "score": 0.9999999862517992,
            "result": "matched"
        },
        "request_id": "cfc7b8d5-f2e2-437b-80e5-d600dfad26e2",
        "user_metadata": {
            "key1": "value1",
            "key2": 2,
            "expiry_date_face": "2023-12-27T03:33:06.307977Z",
        },
        "validate_faces_result": {
            "sanity_verdict": "good",
            "is_live": true,
            "sanity_check": {
                "portrait_sanity": {
                    "score": 1,
                    "verdict": "good"
                },
                "request_id": "9f89377f-4bb4-4ecb-884c-f46f1d7d6099",
                "status": "success"
            },
            "liveness_check": {
                "images": null,
                "is_live": true,
                "request_id": "baee3d03-8af4-421b-8968-a0f6172b4df8",
                "score": 1,
                "status": "success"
            }
        },
        "auth_id": "d4f99f9b-4862-437f-a9c9-608e050d06c6",
        "histories": [
            {
                "id": "f1ca6795-cbd4-4eec-821f-b4ac646db627",
                "client_id": "0ef0f7e9-7f2f-4767-84b8-f76da7701c46",
                "cus_user_id": "3b4bf7b6-088b-4931-9279-9259f5c34fe3",
                "face_auth_id": "887249dc-681c-4231-aff9-67734833aca7",
                "id_card_face_id": "4f959f4a-f5de-4b50-8724-224e709d06c2",
                "live_face_id": "009161c9-9c89-4573-8119-8f513de4449c",
                "created_at": "2023-12-27T03:33:06.307977Z",
                "auth_action": "login",
                "status": "success",
                "result": "",
                "face_type": "selfie"
            },
            {
                "id": "8c23af95-aaa0-4448-bfba-68acce31236e",
                "client_id": "0ef0f7e9-7f2f-4767-84b8-f76da7701c46",
                "cus_user_id": "3b4bf7b6-088b-4931-9279-9259f5c34fe3",
                "face_auth_id": "",
                "id_card_face_id": "4f959f4a-f5de-4b50-8724-224e709d06c2",
                "live_face_id": "009161c9-9c89-4573-8119-8f513de4449c",
                "created_at": "2023-12-21T07:24:19.829484Z",
                "auth_action": "login",
                "status": "failure",
                "result": "image is not liveness",
                "face_type": "id_card"
            }
        ]
    }
}

Request check user of face authentication

This API checks whether a cus_user_id has been registered to the face_authentication system.

1. Request

Client should call this API:

methodURLcontent-type
POST/v1/face_auth_userapplication/json

Body:

JSON
{
    "cus_user_id": string
}

Where

keytyperequireddescription
cus_user_idstringyesuser id of customer

Authentication mechanism is described in Authentication.

Sample Request

bash
curl -X POST \
https://tv-staging.trustingsocial.com/api/v1/face_auth_user \
-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 \
'
{
    "cus_user_id": "3b4bf7b6-088b-4931-9279-9259f5c34fe3"
}
'

2. Response

The response will be a JSON with following format:

JSON
{
    "data": {
        "status": string, // "success" or "failure"
        "verdict" : string, // "registered" or "not_registered"
        "face_types": [string], // list of face types that user has registered (if verdict is "registered")
        "histories": [ // list of registration history if verdict is "registered"
            {
                "id": string, // id of this history
                "client_id": string, // client id
                "cus_user_id": string, // user id
                "face_auth_id": string, // id of selfie image containing user's face
                "id_card_face_id": string, // id of id card image containing user's face
                "live_face_id": string, // id of input image for this login request
                "device_id": string, // device id input for this login request
                "app_id": string, // app id input for this login request
                "latitude": float, // latitude input for this login request
                "longitude": float, // longitude input for this login request
                "created_at": string, // time of this login request
                "auth_action": string, // "register"
                "status": string, // "success" or "failure"
                "result": string, // detail result of this login request
                "metadata": json_object, // metadata input for this login request
                "face_type": string, // type of face used to compare against the input face to authenticate ("selfie", "id_card")
            },
            ... // other history
        ],
        "metadata": {
            ... // key-value if exists
        },
    },
    "errors": [
        {
            "code": string,
            "message": string,
            "detail": {
                "field": string, // optional, which parameter is invalid.
                ... // any other information that can be useful for client
            },
        },
        ... // other errors
    ]
}

The expiry_date of selfie face will be returned in metadata field as expiry_date_face in RFC3339 format.

In case the request processing has been finished successfully, 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.

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 codeerror codedescription
401access_denied_exceptionYou are not authorized to perform the action.
400invalid_parameter_exceptionInput parameter violates a constraint.
400request_time_too_skewedThe X-TV-Timestamp header is expired, need a newer one.
400incorrect_number_of_facesSelfie or original image have more than 1 faces.
404image_not_found_exceptionThe image ID is not found in DB.
404request_not_found_exceptionThe request ID is not found when polling result by id
404face_auth_user_not_found_exceptionThe user of face_auth service not found.
408request_timeout_exceptionRequest takes too long to process
429rate_limit_exceptionThe number of requests exceeded your throughput limit.
500internal_server_errorSome unexpected error occurs while processing the request

Sample Response

JSON
{
    "data": {
        "status": "success",
        "verdict": "registered",
        "face_types": ["selfie", "id_card"],
        "histories": [
            {
                "id": "f1ca6795-cbd4-4eec-821f-b4ac646db627",
                "client_id": "0ef0f7e9-7f2f-4767-84b8-f76da7701c46",
                "cus_user_id": "3b4bf7b6-088b-4931-9279-9259f5c34fe3",
                "face_auth_id": "887249dc-681c-4231-aff9-67734833aca7",
                "id_card_face_id": "4f959f4a-f5de-4b50-8724-224e709d06c2",
                "live_face_id": "009161c9-9c89-4573-8119-8f513de4449c",
                "created_at": "2023-12-27T03:33:06.307977Z",
                "auth_action": "register",
                "status": "success",
                "result": "",
                "face_type": "selfie"
            },
            {
                "id": "8c23af95-aaa0-4448-bfba-68acce31236e",
                "client_id": "0ef0f7e9-7f2f-4767-84b8-f76da7701c46",
                "cus_user_id": "3b4bf7b6-088b-4931-9279-9259f5c34fe3",
                "face_auth_id": "",
                "id_card_face_id": "4f959f4a-f5de-4b50-8724-224e709d06c2",
                "live_face_id": "009161c9-9c89-4573-8119-8f513de4449c",
                "created_at": "2023-12-21T07:24:19.829484Z",
                "auth_action": "register",
                "status": "failure",
                "result": "image is not liveness",
                "face_type": "id_card"
            }
        ],
        "metadata": {
          "key": "value",
          "expiry_date_face": "2023-12-27T03:33:06.307977Z",
        }
    }
}

Request face authentication unregistration

1. Request

Client should call this API:

methodURLcontent-type
POST/v1/face_auth_unregisterapplication/json

Body:

JSON
{
    "cus_user_id": string,
    "device_id": string,
    "app_id": string,
    "lat": float,
    "lng": float,
}

Where

keytyperequireddescriptionmax length
cus_user_idstringyesuser id of customer256
device_idstringnodevice id of user256
app_idstringnoapp id of customer128
latfloatnolatitude of device
lngfloatnolongitude of device

Authentication mechanism is described in Authentication.

Sample Request

bash
curl -X POST \
https://tv-staging.trustingsocial.com/api/v1/face_auth_unregister \
-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 \
'
{
    "cus_user_id": "3b4bf7b6-088b-4931-9279-9259f5c34fe3",
}
'

2. Response

The response will be a JSON with following format:

JSON
{
    "data": {
        "status": string, // "success" or "failure"
        "unregister_id": string, // id of this unregistration request
        "face_auth_user": { // user information after unregistration
            "id": string,
            "client_id": string,
            "access_key_id": string,
            "face_auth_id": string,
            "id_card_face_id": string,
            "cus_user_id": string,
            "device_id": string,
            "app_id": string,
            "latitude": float,
            "longitude": float,
            "metadata": json_object,
            "is_deactivated": bool,
            "is_unregistered": bool,
            "created_at": string_time,
            "updated_at": string_time
        }
    },
    "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 successfully, 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.

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 codeerror codedescription
401access_denied_exceptionYou are not authorized to perform the action.
400invalid_parameter_exceptionInput parameter violates a constraint.
400request_time_too_skewedThe X-TV-Timestamp header is expired, need a newer one.
400incorrect_number_of_facesSelfie or original image have more than 1 faces.
404image_not_found_exceptionThe image ID is not found in DB.
404request_not_found_exceptionThe request ID is not found when polling result by id
404face_auth_user_not_found_exceptionThe user of face_auth service not found.
408request_timeout_exceptionRequest takes too long to process
429rate_limit_exceptionThe number of requests exceeded your throughput limit.
500internal_server_errorSome unexpected error occurs while processing the request

Sample Response

JSON
{
    "data": {
        "status": "success",
        "unregister_id": "d4f99f9b-4862-437f-a9c9-608e050d06c6",
        "face_auth_user": {
            "id": "f1ca6795-cbd4-4eec-821f-b4ac646db627",
            "client_id": "0ef0f7e9-7f2f-4767-84b8-f76da7701c46",
            "access_key_id": "c7d97b7c-f73d-4d62-973e-6eb3e0557ddf",
            "cus_user_id": "3b4bf7b6-088b-4931-9279-9259f5c34fe3",
            "face_auth_id": "",
            "id_card_face_id": "4f959f4a-f5de-4b50-8724-224e709d06c2",
            "live_face_id": "009161c9-9c89-4573-8119-8f513de4449c",
            "device_id": "",
            "app_id": "",
            "latitude": 1.0,
            "longitude": 2.0,
            "metadata": {
              "key1": "value1",
              "key2": 2
            },
            "is_deactivated": false,
            "is_unregistered": true,
            "created_at": "2023-12-27T03:33:06.307977Z",
            "updated_at": "2023-12-28T03:33:06.307977Z",
        }
    }
}

Create a new transaction

1. Request

Client should call this API:

methodURLcontent-type
POST/v1/transactionsapplication/json

Body:

JSON
{
    "reference_id": string,
    "channel_name": string,
    "metadata": dictionary,
    "agent_number": string,
    "agent_name", string,
    "client_transaction_id", string,
    "client_apk_version_number", string,
    "brand_identifier", string,
}

Where

keytyperequireddescriptionsupported countries
reference_idstringnoreference id from clientall
channel_namestringnochannel name from clientall
metadatadictionarynokey-value, key should be string, value should be string, int, float, boolall
agent_numberstringnoagent numberindia
agent_namestringnoagent nameindia
client_transaction_idstringnotransaction id of clientindia
client_apk_version_numberstringnoapk version of clientindia
brand_identifierstringnobrand identifierindia
customer_namestringnocustomer nameindia

Sample Request

bash
curl -X POST \
https://tv-staging.trustingsocial.com/api/v1/transactions \
-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 \
'
{
    "reference_id": "536d2457-bfc0-4249-85f2-8c4053bdec58"
}
'

2. Response

The response will be a JSON with following format:

JSON
{
    "data": {
        "id": uuid,
        "channel_id": uuid,
    },
    "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 API success the HTTP status code will be 200, and data.id will be returned.

If the data.status is "failure", the "errors" field will tell you why it failed.

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 codeerror codedescription
401access_denied_exceptionYou are not authorized to perform the action.
400invalid_parameter_exceptionInput parameter violates a constraint.
400request_time_too_skewedThe X-TV-Timestamp header is expired, need a newer one.
408request_timeout_exceptionRequest takes too long to process
429rate_limit_exceptionThe number of requests exceeded your throughput limit.
500internal_server_errorSome unexpected error occurs while processing the request

Authentication mechanism is described in Authentication.

Sample Response

JSON
{
    "data": {
        "id": "cfc7b8d5-f2e2-437b-80e5-d600dfad26e2",
        "channel_id": "416ab0e7-13a2-4b4b-9304-03bb8612d817"
    }
}

Finish a transaction

1. Request

Client should call this API:

methodURLcontent-type
POST/v1/transactions/{transaction_id}/finishapplication/json

Body:

JSON
{
    "vilcaf_number", string,
}

Where

keytyperequireddescriptionsupported countries
vilcaf_numberstringnoCAF Numberindia
status_codeintnostatus codeindia

Sample Request

bash
curl -X POST \
https://tv-staging.trustingsocial.com/api/v1/transactions/3b4bf7b6-088b-4931-9279-9259f5c34fe3/finish \
-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 \
'
{
    "vilcaf_number": "CAF_123456789"
}
'

2. Response

The response will be a JSON with following format:

JSON
{
    "data": {
        "id": uuid,
    },
    "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 API success the HTTP status code will be 200, and data.id will be returned.

If the data.status is "failure", the "errors" field will tell you why it failed.

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 codeerror codedescription
401access_denied_exceptionYou are not authorized to perform the action.
400invalid_parameter_exceptionInput parameter violates a constraint.
400request_time_too_skewedThe X-TV-Timestamp header is expired, need a newer one.
408request_timeout_exceptionRequest takes too long to process
429rate_limit_exceptionThe number of requests exceeded your throughput limit.
500internal_server_errorSome unexpected error occurs while processing the request

Authentication mechanism is described in Authentication.

Sample Response

JSON
{
    "data": {
        "id": "416ab0e7-13a2-4b4b-9304-03bb8612d817"
    }
}

Get client settings

1. Request

Client should call this API:

methodURLcontent-type
GET/v1/client_settingsapplication/json

With following parameters:

fieldtyperequireddescription
flow_idstringnocustomize SDK setting based on your business

To get settings to depend on a specific device/version, you should add these headers

headertyperequireddescription
X-TV-Device-ModelstringnoSpecify device model
X-TV-SDK-VersionstringnoSpecify SDK version from TrustingSocial
X-TV-OS-PlatformstringnoSpecify OS platform as AndroidiOSWeb
X-TV-OS-VersionstringnoSpecify OS version

Sample Request

bash
curl -X GET \
https://tv-staging.trustingsocial.com/api/v1/client_settings
-H 'Authorization: TV <YOUR ACCESS KEY>:<CREATED SIGNATURE>' \
-H 'X-TV-Timestamp: 2019-04-21T18:00:15+07:00' \
-H 'Content-Type: application/json'

2. Response

The response will be a JSON with following format:

JSON
{
    "data": {
        "country": string, // client's country: "in", "vn", "id"
        "card_types": [
            {
                "code": string, // "in.aadhaar"
                "name": string, // "Aadhaar card",
                "orientation": string, // "horizontal", "vertical"
                "has_back_side": bool, // true, false
                "front_qr": {
                    "exist": bool, // true, false
                    "type": string, // "qr_code", "bar_code"
                    "width_height_ratio": float, // width/height, example 1.0, 2.5
                },
                "back_qr": {
                    "exist": bool, // true, false
                    "type": string, // "qr_code", "bar_code"
                    "width_height_ratio": float, // width/height, example 1.0, 2.5
                },
            },
            ... // other supported card types of client's country
        ],
        "settings": {
            "scan_qr": string, // "none", "separate_step", "with_card",
            "web_app_crop_face": string // only for webapp 'no', 'auto', 'hybrid'
            "web_ui": {
                "show_score": bool // true, false: show/hide score of each result
            }
            // no means web app does not need to crop face
            // auto means web app automatically crop face
            // hybrid means web app show UI with suggestion to let customer crop face
            "liveness_modes": []string,
            "zoom_issue_devices":[]string, // define list devices have issue with zoom image. "*" means apply solution for all devices
            // Else specify list devices need to apply new solution ["Motorola Moto E (4) Plus","Xiaomi Redmi Note 5 Pro"]
            // liveness modes could be these value
            // passive - enable passive liveness on mobile
            // active - enable active liveness on mobile
            "selfie_enable_detect_multiple_face": bool, // true, false
            "enable_compare_faces": bool,
            "enable_verify_face_liveness": bool,
            "enable_read_id_card_info": bool,
            "enable_verify_portrait_sanity": bool, // true, false
            "enable_verify_id_card_sanity": bool, // true, false
            "enable_detect_id_cards": bool, // true, false
            // true mean client automatically detect multiple face when capture selfie image
            "selfie_camera_options": []string,
            "enable_encryption": bool, // true, false
            "support_transaction": bool, // true, false
            ... // other settings
        },
    },
    "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 of success, the HTTP status code will be 200.

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 codeerror codedescription
401access_denied_exceptionYou are not authorized to perform the action.
408request_timeout_exceptionRequest takes too long to process
429rate_limit_exceptionThe number of requests exceeded your throughput limit.
500internal_server_errorSome unexpected error occurs while processing the request

Sample Response

JSON
{
    "data": {
        "card_types": [
            {
                "code": "vn.national_id",
                "name": "CMND cũ / CMND mới / CCCD / Hộ chiếu",
                "orientation": "horizontal",
                "has_back_side": true,
                "front_qr": {
                    "exist": false
                },
                "back_qr": {
                    "exist": false
                }
            }
        ],
        "country": "vn",
        "settings": {
            "enable_compare_faces": true,
            "enable_convert_pdf": true,
            "enable_detect_id_card_tampering": true,
            "enable_encryption": false,
            "enable_face_retrieval": true,
            "enable_index_faces": true,
            "enable_read_id_card_info": true,
            "enable_verify_face_liveness": true,
            "enable_verify_id_card_sanity": true,
            "enable_verify_portrait_sanity": true,
            "liveness_modes": [
                "active",
                "passive"
            ],
            "scan_qr": "none",
            "selfie_camera_options": [
                "front"
            ],
            "selfie_enable_detect_multiple_face": true,
            "support_transaction": false,
            "utilities": {
                "length_video_sec": 5,
                "num_of_photo_taken": 3,
                "photo_res": "640x640",
                "timing_take_photo_sec": "1,2.5,4"
            },
            "web_app_crop_face": "none",
            "web_ui": {
                "index_collections": [
                    {
                        "id": "id_card",
                        "label": "Mặt trước CMND/CCCD/Passport"
                    },
                    {
                        "id": "portrait",
                        "label": "Hình ảnh selfie của khách hàng"
                    }
                ],
                "show_score": false
            }
        }
    }
}

Verify identity

The API verifies identity from two image_id received from the upload image api. Main function of this service is to know if the id card and people in the image is trusted or not.

1. Request

Client should call this API:

methodURLcontent-type
POST/v1/verify_identity_syncapplication/json

Body:

JSON
{
    "card_type": string,
    "image1": {
        "id": string,
        "base64": string,
        "label": string,
        "metadata": string_json,
    },
    "image2": {
        "id": string,
        "base64": string,
        "label": string,
        "metadata": string_json,
    }
}

Where

keytyperequireddescription
card_typestringyestype of identity card, described at Card type table
image1ImageDatayesimage of the identity card's front side
image2ImageDatanoportrait image

Which each image's parameters contains:

keytyperequireddescription
idstringnoID of image is returned from API Upload
base64stringnobase64 encoded text of image data
labelstringnolabel of the image as described at Label table
metadatastring_jsonnokey-value string, key should be string, value should be string, int, float, bool. Example "{\"id\":\"123456789\",\"type\":1}"

Note:

  • If you use base64, label and metadata, omit parameter id.
  • If you use 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.

Sample Request

bash
curl -X POST \
https://tv-staging.trustingsocial.com/api/v1/verify_identity_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 \
'
{
    "card_type": "vn.national_id",
    "image1": {
        "id": "7db00808-0416-45cf-a5cb-3b6dfbd7bb74"
    },
    "image2": {
        "id": "a4facba3-334b-41fb-97e3-4766cb70ae29"
    }
}
'

2. Response

The response will be a JSON with following format:

JSON
{
    "data": {
        "status": string, // "success" or "failure"
        "verify_identity": {
            "score": float,
            "verdict": string // "good", "age_not_match",...
            "details": [ // optional if client needs to provide
                { "verdict": string, "score": float, "name": string, "info": string },
                { "verdict": string, "score": float, "name": string, "info": string },
            ],
            "score_details": [ // optional if client needs to provide
                { "verdict": string, "score": float, "name": string, "info": string },
                { "verdict": string, "score": float, "name": string, "info": string },
            ]
        },
        "image1_id": string, // ID of the image
        "image2_id":string, // ID of the image2
    },
    "errors": [
        {
            "code": string,
            "message": string,
            "detail": {
                "field": string, // optional, which parameter is invalid.
                ... // any other information that can be useful for client
            },
        },
        ... // 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 codedescriptionsupported countries
age_not_matchage of people in the id card and portrait not matchall

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 codeerror codedescription
401access_denied_exceptionYou are not authorized to perform the action.
400invalid_parameter_exceptionInput parameter violates a constraint.
400request_time_too_skewedThe X-TV-Timestamp header is expired, need a newer one.
404image_not_found_exceptionThe image ID is not found in DB.
404request_not_found_exceptionThe request ID is not found when polling result by id
408request_timeout_exceptionRequest takes too long to process
429rate_limit_exceptionThe number of requests exceeded your throughput limit.
500internal_server_errorSome unexpected error occurs while processing the request

Sample Response

JSON
{
  "data": {
    "image1_id": "1956f390-0db8-4fbb-b818-284877f245fd",
    "image2_id": "41da97f1-61e2-4da0-8de4-c0734b3a4fdd",
    "status": "success",
    "verify_identity": {
      "details": null,
      "score": 1,
      "score_details": null,
      "verdict": "good"
    }
  }
}

Read doc info

The read doc info api takes an array of images as the input. Main function of this service is to extract text from supported legal documents. It also detects the location of the document inside the uploaded image.

1. Request

Client should call this API:

methodURLcontent-type
POST/v1/read_doc_info_syncapplication/json

Body:

JAVASCRIPT
{
    "doc_type": string,
    "images": [{
        "id": string,
        "base64": string,
        "label": string,
        "metadata": string_json,
    }]
}

Where

keytyperequireddescription
doc_typestringyestype of document
imagesList of ImageDatayesimages of document

doc_type should be one of following values:

doc_typedescriptionsupported countries
vn.business_licenseAny business license in Vietnamvietnam

Which each image's parameters contains:

keytyperequireddescription
idstringnoID of image is returned from API Upload
base64stringnobase64 encoded text of image data
labelstringnolabel of the image as described at Label table
metadatastring_jsonnokey-value string, key should be string, value should be string, int, float, bool. Example "{\"id\":\"123456789\",\"type\":1}"

User can specify 4 corner's coordinates of each image, these information will be send in metadata:

JSON
"doc_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 },
},

Note:

  • If you use base64, label and metadata, omit parameter id.
  • If you use 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.

Sample Request

bash
curl -X POST \
https://tv-staging.trustingsocial.com/api/v1/read_doc_info_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 \
'
{
    "doc_type": "vn.business_license",
    "images": [
        {
            "id": "7db00808-0416-45cf-a5cb-3b6dfbd7bb74"
        },
        {
            "id": "a4facba3-334b-41fb-97e3-4766cb70ae29"
        }
    ]
}
'

2. Response

The response will be a JSON with following format:

JAVASCRIPT
{
    "request_id": string, // ID of the request
    "status": string, // "success" or "failure"
    "data": {
        "images": [{
            "id": string,
            "transformed_image"{ // optional, in case the image is transformed
                "id": string, // ID of the transformed image
                "folder": string, // the folder contains the transformed image file
                "storage": string, // name of the storage which stores the transformed image file
            },
            "doc_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 },
            },
            "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
                ]
            },
        },
        // other image
        ]
        "doc_information": [ // merged and normalized information from OCR of all pages in document
            {
                "field": string, // field name ("identity_number", "full_name", "birth_date")
                "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 codedescriptionsupported countries
image_too_blurthe input image is too blurall
image_too_darkthe input image is too darkall
image_too_brightthe input image is too bright (glare)all
image_has_no_facesthe input image has no facesall

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 codeerror codedescription
401access_denied_exceptionYou are not authorized to perform the action.
400invalid_parameter_exceptionInput parameter violates a constraint.
400request_time_too_skewedThe X-TV-Timestamp header is expired, need a newer one.
404image_not_found_exceptionThe image ID is not found in DB.
404request_not_found_exceptionThe request ID is not found when polling result by id
408request_timeout_exceptionRequest takes too long to process
429rate_limit_exceptionThe number of requests exceeded your throughput limit.
500internal_server_errorSome unexpected error occurs while processing the request

Sample Response

JSON
{
  "data": {
    "doc_information": [
      {
        "field": "doc_name",
        "value": "GIẤY CHỨNG NHẬN ABC"
      },
      {
        "field": "business_number",
        "value": "0123456789"
      },
      {
        "field": "first_registration_date",
        "value": "01/01/2001"
      },
      {
        "field": "update_date",
        "value": "01/11/2017"
      },
      {
        "field": "business_name_vi",
        "value": "CÔNG TY TNHH TRUSTING SOCIAL"
      },
      ...
    ],
    "images": [
      {
        "doc_box": {
          "bottom_left": {
            "x": 68,
            "y": 998
          },
          "bottom_right": {
            "x": 798,
            "y": 1002
          },
          "top_left": {
            "x": 88,
            "y": 27
          },
          "top_right": {
            "x": 764,
            "y": 3
          }
        },
        "id": "ae0d296b-8e39-413f-bdc5-93b53628d2d1",
        "ocr": null,
        "transformed_image_id": ""
      }
    ],
    "status": "success"
  }
}

Verify NFC

The verify nfc api takes the datagroups inside an NFC chip which can be extracted from our SDK as the input. Main function of this service is to verify the legitimate of an NFC chip. It also extracts the information embedded in the chip.

1. Request

Client should call this API:

methodURLcontent-type
POST/v1/verify_nfcapplication/json

Body:

JAVASCRIPT
{
    "sod": string,
    "dg1": string,
    "dg2": string,
    "dg13": string,
    "dg14": string,
    "dg15": string,
    "com": string,
    "cccd": string,
    "force_call_bca": bool,
    "clone_status": string,
    "card_image_id": string
}

Where

keytyperequireddescription
sodstringyesSOD data (Document Security Object) extracted from NFC data and encoded as base64 string
dg1stringnodatagroup 1 extracted from NFC data and encoded as base64 string
dg2stringnodatagroup 2 extracted from NFC data and encoded as base64 string
dg13stringnodatagroup 13 extracted from NFC data and encoded as base64 string
dg14stringnodatagroup 14 extracted from NFC data and encoded as base64 string
dg15stringnodatagroup 15 extracted from NFC data and encoded as base64 string
comstringnoCOM data (the common data) extracted from NFC data and encoded as base64 string
cccdstringnothe id number of CCCD
force_call_bcaboolnoforce check with BCA (ignore the old BCA_status)
clone_statusstringnothe clone_status of the NFC chip, can be good, alert, error
card_image_idstringnothe image_id of id_card (front or back) to store nfc result to for later use

Authentication mechanism is described in Authentication.

  • Note: either dg13 or cccd must be provided.

Sample Request

bash
curl -X POST \
https://tv-staging.trustingsocial.com/api/v1/verify_nfc \
-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 \
'
{
    "sod": "JVBERi0xLjMNCiXi...cxNA0KJSVFT0YNCg",
    "dg1": "JVBERi0xLjMNCiXi...cxNA0KJSVFT0YNCg",
    "dg2": "JVBERi0xLjMNCiXi...cxNA0KJSVFT0YNCg",
    "dg13": "JVBERi0xLjMNCiXi...cxNA0KJSVFT0YNCg",
    "dg14": "JVBERi0xLjMNCiXi...cxNA0KJSVFT0YNCg",
    "dg15": "JVBERi0xLjMNCiXi...cxNA0KJSVFT0YNCg"
}
'

2. Response

The response will be a JSON with following format:

JAVASCRIPT
{
  "data": {
    "request_id": string,
    "status": string, // "success" or "failure"
    "card_information": [ // card information embedded in the NFC chip
      {
        "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
    ],
    "image": {
      "id": string // image_id of the image embedded in the NFC chip
    },
    "nfc_verification": { // the verification result
      "bca_status": { // verification result from the authorities
        "verdict": string // "good", "alert", "not_check", ...
        "error_code": string, // error code in case verdict not good
        "error_message": string, // error message in case verdict not good,
        "details": { // detail response from the authorities
            "bca_response": {...}, // raw response from the authorities
            "is_from_cache": bool, // whether the response is from cache or not
            "response_validity": string, // validity check of the raw response ("good", "alert", "not_check")
            "verified_at": string_timestamp // time when the verification is done
        }
      },
      "integrity_status": { // integrity verification result
          "verdict": string // "good", "alert", "not_check", ...
          "error_code": string, // error code in case verdict not good
          "error_message": string, // error message in case verdict not good
      },
      "clone_status": { // clone status that user pass in the input (empty if not provided)
        "verdict": string // "good", "alert", "not_check", ...
      }
      "verdict": "string" // overall verification result ("good", "alert", "not_check")
    },
  },
  "errors": [
            {
                "code": string,
                "message": string,
                "detail": {
                    "field": string, // optional, which parameter is invalid.
                    ... // any other information that can be useful for client
                },
            },
            ... // 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.

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 codeerror codedescription
401access_denied_exceptionYou are not authorized to perform the action.
400invalid_parameter_exceptionInput parameter violates a constraint.
400request_time_too_skewedThe X-TV-Timestamp header is expired, need a newer one.
404request_not_found_exceptionThe request ID is not found when polling result by id
404image_not_found_exceptionThe image ID of id_card is not found
408request_timeout_exceptionRequest takes too long to process
429rate_limit_exceptionThe number of requests exceeded your throughput limit.
500internal_server_errorSome unexpected error occurs while processing the request

Sample Response

JSON
{
  "data": {
    "card_information": [
      {
        "confidence_score": 1,
        "confidence_verdict": "SURE",
        "field": "id_no",
        "value": "0123456789"
      },
      {
        "confidence_score": 1,
        "confidence_verdict": "SURE",
        "field": "full_name",
        "value": "Nguyen Van A"
      },
      {
        "confidence_score": 1,
        "confidence_verdict": "SURE",
        "field": "birthday",
        "value": "01/02/2003"
      },
      ...
    ],
    "image": {
      "id": "256ecffe-74a0-4945-a9aa-23f0cfba540b"
    },
    "nfc_verification": {
      "bca_status": {
        "error_code": "",
        "error_message": "",
        "verdict": "good"
      },
      "integrity_status": {
        "error_code": "",
        "error_message": "",
        "verdict": "good"
      },
      "verdict": "good"
    },
    "server_infos": {
      "timestamp": "2023-03-17T12:52:14+07:00"
    },
    "status": "success"
  }
}

Check NFC

The check_nfc api checks whether an ID card has been verified NFC by TrustVision before or not.

1. Request

Client should call this API:

methodURLcontent-type
POST/v1/check_nfcapplication/json

Body:

JAVASCRIPT
{
    "id_num": string,
    "issue_date": string
}

Where

keytyperequireddescription
id_numstringyesID Number in raw format or SHA256 hash
issue_datestringnoIssue date in format DD/MM/YYYY

Authentication mechanism is described in Authentication.

Sample Request

bash
curl -X POST \
https://tv-staging.trustingsocial.com/api/v1/check_nfc \
-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 \
'
{
    "id_num": "0123456789",
    "issue_date": "01/01/2001"
}
'

2. Response

The response will be a JSON with following format:

JAVASCRIPT
{
  "data": {
      "status": string, // "success" or "failure"
      "nfc_check": {
        "status": string, // "verified" or "not_verified"
        "hash_sod": string, // hash of SOD data (SHA512) if found
        "input_fields": string[], // list of input fields if status = "verified" (e.g. ["dg1", "dg13", "dg2", "dg14", "dg15", "com", "cccd"])
      },
  },
  "errors": [
      {
          "code": string,
          "message": string,
          "detail": {
              "field": string, // optional, which parameter is invalid.
              ... // any other information that can be useful for client
          },
      },
      ... // 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.

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 codeerror codedescription
401access_denied_exceptionYou are not authorized to perform the action.
400invalid_parameter_exceptionInput parameter violates a constraint.
400request_time_too_skewedThe X-TV-Timestamp header is expired, need a newer one.
404request_not_found_exceptionThe request ID is not found when polling result by id
408request_timeout_exceptionRequest takes too long to process
429rate_limit_exceptionThe number of requests exceeded your throughput limit.
500internal_server_errorSome unexpected error occurs while processing the request

Sample Response

JSON
{
  "data": {
      "status": "success",
      "nfc_check": {
        "status": "verified",
        "hash_sod": "ebc713d2781df95e69fe83eacb1be93...",
        "input_fields": ["dg1", "dg13", "dg2", "dg14", "dg15", "com", "cccd"]
      }
  }
}

Index faces video

The index faces video service allows one to index a frame from a video that passes portrait sanity and add it to a collection. The purpose of this activity is to build a collection of faces that can be retrieved using search faces api.

1. Request

Client should call this API:

methodURLcontent-type
POST/v1/index_faces_videoapplication/json

Body:

JSON
{
    "video": {
        "id": string,
        "base64": string,
        "label": string,
        "metadata": string_json,
    },
    "collection": string,
}

Where

keytyperequireddescription
videoVideoDatayesvideo to index face. Should use video has the face
collectionstringnoindex faces to this collection. case-sensitive

Which each video's parameters contains:

keytyperequireddescription
idstringnoID of video is returned from API Upload
base64stringnobase64 encoded text of video data
labelstringnolabel of the video as described at Label table
metadatastring_jsonnokey-value string, key should be string, value should be string, int, float, bool. Example "{\"id\":\"123456789\",\"type\":1}"

Note:

  • If you use base64, label and metadata, omit parameter id.
  • If you use id (result id is returned from Upload File API), omit parameter base64, label and metadata.
  • If not set collection, default collection will be used.

Clients can provide image data to the TrustVision API by specifying the ID the video by using upload file API, or by sending the file data as base64-encoded text.

Authentication mechanism is described in Authentication.

Sample Request

bash
curl -X POST \
https://tv-staging.trustingsocial.com/api/v1/index_faces_video \
-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 \
'
{
    "video": {
        "id": "a4facba3-334b-41fb-97e3-4766cb70ae29"
    }
}
'

2. Response

JSON
{
    "data": {
        "request_id": string,
        "image": {
          "id": string, // id of the image
          "transformed_image_id": string // optional, just in case the image is transformed
        },
        "video_id": string, // id of the input video
        "status": string, // "success" or "failure"
    },
    "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.

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 codeerror codedescription
401access_denied_exceptionYou are not authorized to perform the action.
400invalid_parameter_exceptionInput parameter violates a constraint.
400request_time_too_skewedThe X-TV-Timestamp header is expired, need a newer one.
404image_not_found_exceptionThe image ID is not found in DB.
404request_not_found_exceptionThe request ID is not found when polling result by id
408request_timeout_exceptionRequest takes too long to process
429rate_limit_exceptionThe number of requests exceeded your throughput limit.
500internal_server_errorSome unexpected error occurs while processing the request

Sample Response

JSON
{
    "data": {
        "status": "success",
        "image": {
          "id": "a4facba3-334b-41fb-97e3-4766cb70ae29"
        },
        "video_id": "c679b398-8dc3-4112-ab37-71b66f6d2e04",
        "request_id": "dfdef016-e89b-4da4-ae17-5844f909c947"
    }
}