ID Card · Standard API · eKYC Core

Verify ID card

POST/v1/verify_id_card_sanity_sync

Checks the sanity of one or two ID card images and returns a good verdict, or the first quality issue found.

Request

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

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
image1stringRequiredimage of the identity card's front side or back side (incase image2 empty)
image2stringOptionalimage of the identity card's back side
special_id_typestringOptionalid string (provided by admin) to identify special use-case. Omit this param to use the default.
  • 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.

The ImageData shape — id, base64, label and metadata — is 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,
    },
    "special_id_type": string,
}

Sample request

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

Response

data.card_sanity carries the verdict — good, or the first issue found — with a score in the range 0-1; on a verdict other than good the higher the score, the more likely the card is unqualified. 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.

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.

A card that passes every check comes back like this:

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

Failure codes

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

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.