Common · Standard API · eKYC Core

Full eKYC

POST/v1/ekyc

Runs the whole eKYC chain — sanity, ID tampering, OCR, face matching, liveness and face retrieval — in one call, and returns the card information, face-match pairs and liveness verdict together.

Request

MethodPOST
Path/v1/ekyc
Content-Typeapplication/json
Auth requiredYes — HMAC signing

The settings at the backend control which services a call actually runs. 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.

NameTypeRequiredDescription
card_typestringRequiredtype of identity card, described at Card type table
image1ImageDataRequiredimage of the identity card's front side
image2ImageDataOptionalimage of the identity card's back side
selfies[]ImageDataRequiredlist selfie images of customer. Max 3 images
  • 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.

Each image is an ImageData object — id, base64, label and metadata — defined once on Common objects.

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,
        },
        ...
    ]
}

Sample request

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

Response

data.status carries the verdict. 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.

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
    ]
}

A successful call returns the merged card information, one entry per compared pair of faces, and the liveness verdict:

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
        }
    }
}

Failure codes

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

The codes above are the ones documented for this endpoint. Response errors on the Overview lists the codes for the eKYC Core surface as a whole — the two lists do not match on every endpoint.