NFC · Standard API · eKYC Core

Verify NFC

POST/v1/verify_nfc

Verifies the datagroups read from an NFC chip and returns the chip's legitimacy verdict together with the identity information embedded in it.

Request

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

The datagroups inside the chip are extracted by the TrustVision SDK and passed here as base64-encoded strings.

NameTypeRequiredDescription
sodstringRequiredSOD data (Document Security Object) extracted from NFC data and encoded as base64 string
dg1stringOptionaldatagroup 1 extracted from NFC data and encoded as base64 string
dg2stringOptionaldatagroup 2 extracted from NFC data and encoded as base64 string
dg11stringOptionaldatagroup 11 extracted from NFC data and encoded as base64 string
dg12stringOptionaldatagroup 12 extracted from NFC data and encoded as base64 string
dg13stringOptionaldatagroup 13 extracted from NFC data and encoded as base64 string
dg14stringOptionaldatagroup 14 extracted from NFC data and encoded as base64 string
dg15stringOptionaldatagroup 15 extracted from NFC data and encoded as base64 string
comstringOptionalCOM data (the common data) extracted from NFC data and encoded as base64 string
cccdstringOptionalthe id number of CCCD
force_call_bcaboolOptionalforce check with BCA (ignore the old BCA_status)
clone_statusstringOptionalthe clone_status of the NFC chip, can be good, alert, error
card_image_idstringOptionalthe image_id of id_card (front or back) to store nfc result to for later use
card_typestringOptionaltype of identity card, described at Card type table. Default is vn.national_id
  • For Vietnam card types (CCCD/TCC), either dg13 or cccd must be provided.
JSON
{
    "sod": string,
    "dg1": string,
    "dg2": string,
    "dg11": string,
    "dg12": string,
    "dg13": string,
    "dg14": string,
    "dg15": string,
    "com": string,
    "cccd": string,
    "force_call_bca": bool,
    "clone_status": string,
    "card_image_id": string,
    "card_type": string
}

Sample request

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

Response

nfc_verification.verdict carries the overall verification result — good, alert or not_check. Beside it, bca_status is the result from the authorities, integrity_status the integrity check, and clone_status the clone status you passed in. A 200 only means the request finished processing: data.status is "success" or "failure" according to whether it was processed, so neither it nor the HTTP status says anything about the chip. The information read out of the chip comes back under card_information, and errors uses the shared response envelope.

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

A chip that verifies cleanly comes back like this:

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

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

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.