OCR
Indonesian_ID_Card
Indonesian_ID_Card

# Description

Detect and recogize Indonisian ID Cards

# Invoke URL

https://api-idn.megvii.com/faceid/v3/indonesia_ocr

WARNING:Please use HTTPS protocol for connections in production environments. HTTP protocol has safety risk due to lack of encryption; therefore, using HTTP may not guarantee service reliability.

# Invoke Method

POST  WARNING:please use "form-data" format to request.

API description

This API generates an encrypted signature "sign" using the API key and secret, along with a photo of an ID card, to obtain the recognition result of the ID card.
This API does not check image quality. Please ensure the quality of the image provided. Poor image quality may result in the inability to recognize the ID card or certain fields on the ID card.

# Parameters

Required/Optional Parameter Type Description
Required sign String The signature of the caller to this API. For more information about generation of a signature, please refer to API authentication.
Required sign_version String The version of the signature algorithm. Please use hmac_sha1 as parameter.
Required image File A photo of the ID card taken by the user.(Please ensure the quality of the photo. This API does not check photo quality.)
Optional biz_no String The business serial number.
Optional return_photo String This specifies whether to return the portrait. Valid values::
  • "1":Return
  • "0":Not return
The default value is "0".

# Return values

Parameter Type Description
request_id String The unique string to identify each request. This field is always returned unless a 404 (API_NOT_FOUND) error or a 403 (AUTHORIZATION_ERROR) error occurs
time_used Int The time taken by the entire request in milliseconds. This field is always returned.
biz_no String The business serial number that is provided as an input parameter.
result Int The result code for ID card recognition. Valid values:
(If multiple ID cards are present in the image, only the information of the ID card with the highest confidence is returned.)
  • 1001: This indicates that an ID card is recognized (normally) without issues and the ID card information is returned.
  • If the recognition is unsuccessful, the issue will be returned with an error code.
idcard_face_image String The photo on the ID card in Base64.
If no face is detected or the face image is of poor quality, null is returned.
issued_province Dict The province where the card is issued. This is returned if the recognition is successful.
issued_city Dict The city where the card is issued. This is returned if the recognition is successful.
idcard_number Dict The number of the ID card. This is returned if the recognition is successful.
name Dict The name on the ID card. This is returned if the recognition is successful.
birth_place Dict The birthplace on the ID card. This is returned if the recognition is successful.
birthday Dict The date of birth on the ID card. This is returned if the recognition is successful.
gender Dict The gender on the ID card. This is returned if the recognition is successful.
blood_type Dict The blood type on the ID card. This is returned if the recognition is successful.
address_area Dict The address on the ID card. This is returned if the recognition is successful.
address_building Dict The unit and building number on the ID card. This is returned if the recognition is successful.
address_quarters Dict The residence community on the ID card. This is returned if the recognition is successful.
address_districts Dict The subdistrict on the ID card. This is returned if the recognition is successful.
faith Dict The religion on the ID card. This is returned if the recognition is successful.
marriage_type Dict The marital status on the ID card. This is returned if the recognition is successful.
profession Dict The occupation on the ID card. This is returned if the recognition is successful.
nationality Dict The nationality on the ID card. This is returned if the recognition is successful.
valid_end Dict The expiration date on the ID card. This is returned if the recognition is successful.
issued_area Dict The place where the card is issued (the location below the holder's photo). This is returned if the recognition is successful.
valid_start Dict The date when the card is issued. This is returned if the recognition is successful.
card_rect Dict This dictionary contains the coordinates of the four corners of the card. For example:
"rt"{ "x":324, "y":578 }// "lt"{ "x":324, "y":226 }// "lb"{ "x":398, "y":226 }// "rb"{ "x":398, "y":578 }//
ERROR String The error code returned if an error occurs. For more information, see the "Error message" section below.

Structure of the recognition fields

Field Type Description
+result String The content recognized.
+condifence Float The confidence score. This is a float ranging from 0 to 100 with 3 decimal places.
+rect Dict This dictionary contains the coordinates of the four corners of the content area. For example:
"rt"{ "x":324, "y":578 }// "lt"{ "x":324, "y":226 }// "lb"{ "x":398, "y":226 }// "rb"{ "x":398, "y":578 }//

# Error messages

HTTP status code
Error message Description
400 IMAGE_ERROR_UNSUPPORTED_FORMAT No ID card was found in the image, or the image quality is too poor to recognize.
400 BAD_ARGUMENTS:<key> An error occurred while parsing a parameter (for example, a parameter is a number but a string is used, the value is too long, or the photo cannot be parsed).
400 MISSING_ARGUMENTS: <key> A required parameter is missing.
403 AUTHORIZATION_ERROR The signature is invalid.
403 AUTHORIZATION_ERROR: The api_key is disabled, call limit is reached, no permission to call this API, or no permission to call this API with the current method.
value:
  • 5001:No permission to call this API with the api_key or the api_key is disabled;
  • 5002:Unauthorized IP. (reserved)
  • 5007:The limit to call this API with the api_key is reached (only when the api_key is a test key).
403 CONCURRENCY_LIMIT_EXCEEDED The concurrency limit is exceeded.
404 API_NOT_FOUND The API does not exist.
413 Request Entity Too Large The size of a photo in the request exceeds 10 MB. This error is returned in text instead of JSON.
500 INTERNAL_ERROR Internal server error. If this error occurs, send the request again. If this error persists, contact FaceID customer service or business support.

# API authentication

Description

To protect the api_secret when the API is called, a signature mechanism is used to secure communication between servers.

Signature algorithm

raw strings: a=[api_key]&b=[expire_time]&c=[current_time]&d=[random]

Field

Field Value Description
a api_key This serves as the username and can be obtained in the FaceID console.
b expire_time The expiration time of the signature. This is a Unix epoch timestamp in seconds
c current_time The timestamp when the signature is generated, in seconds. The current_time must be earlier than expire_time.
d random A custom unsigned decimal integer with a maximum length of 10 digits.

Note: the design of expire_time is for users to use the signature multiple times in a short period.

# Generate a signature

Use the HMAC-SHA1 algorithm to encrypt the request.

Signature generation process:

  • Concatenate each fields to create a raw string
  • Use api_secret to sign the raw string with HMAC-SHA1 algorithm.
  • Join the generated signature and the raw and encode it in Base64 to generate a sign signature.

calculation code:

raw = "a={}&b={}&c={}&d={}".format(api_key, expire_time, current_time, random) 
sign_tmp = HMAC-SHA1(api_secret, raw)
sign = Base64(''.join(sign_tmp, raw))

Note:

  • The standard Base64 encoding is used here, instead of a url-safe Base64 encoding.
  • You must use the same set of api_secret and api_key, which can be obtained in the FaceID console.

# Demo code

Python demo code

import time
import hashlib
import base64
import random
import hmac
api_key = "your api_key"
api_secret = "your api_secret"
valid_durtion = 100 # valid for 100s
current_time = int(time.time())
expire_time = current_time + valid_durtion
rdm = ''.join(random.choice("0123456789") for i in range(10))
raw = "a={}&b={}&c={}&d={}".format(api_key, expire_time, current_time, rdm)
sign_tmp = hmac.new(api_secret, raw, hashlib.sha1).digest()
sign = base64.b64encode(sign_tmp + raw)

Java demo code

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;
import java.util.Random;
 
public class HmacSha1Sign {
 
    /**
     * generate signature
     *
     * @param apiKey
     * @param secretKey
     * @param expired
     * @return
     * @throws Exception
     */
    public static String genSign(String apiKey,  String secretKey, long expired) throws Exception {
        long now = System.currentTimeMillis() / 1000;
        int rdm = Math.abs(new Random().nextInt());
        String plainText = String.format("a=%s&b=%d&c=%d&d=%d", apiKey, now + expired, now, rdm);
        byte[] hmacDigest = HmacSha1(plainText, secretKey);
        byte[] signContent = new byte[hmacDigest.length + plainText.getBytes().length];
        System.arraycopy(hmacDigest, 0, signContent, 0, hmacDigest.length);
        System.arraycopy(plainText.getBytes(), 0, signContent, hmacDigest.length,
                plainText.getBytes().length);
        return encodeToBase64(signContent).replaceAll("[\\s*\t\n\r]", "");
    }
 
    /**
     * generate base64 encoding
     *
     * @param binaryData
     * @return
     */
    public static String encodeToBase64(byte[] binaryData) {
        String encodedStr = Base64.getEncoder().encodeToString(binaryData);
        return encodedStr;
    }
 
    /**
     * generate hmacsha1 sign
     *
     * @param binaryData
     * @param key
     * @return
     * @throws Exception
     */
    public static byte[] HmacSha1(byte[] binaryData, String key) throws Exception {
        Mac mac = Mac.getInstance("HmacSHA1");
        SecretKeySpec secretKey = new SecretKeySpec(key.getBytes(), "HmacSHA1");
        mac.init(secretKey);
        byte[] HmacSha1Digest = mac.doFinal(binaryData);
        return HmacSha1Digest;
    }
 
    /**
     * generate hmacsha1 sign
     *
     * @param plainText
     * @param key
     * @return
     * @throws Exception
     */
    public static byte[] HmacSha1(String plainText, String key) throws Exception {
        return HmacSha1(plainText.getBytes(), key);
    }
}

Objective-C demo code

#import "ViewController.h"
#import <CommonCrypto/CommonHMAC.h>
#import <CommonCrypto/CommonCryptor.h>
#import <math.h>
#define api_key @"你的api_key"
#define api_secret @"你的api_secret"

@interface ViewController ()
@end

@implementation ViewController
- (void)viewDidLoad {
 [super viewDidLoad];
 NSString* sign = [self getSignStr];
 NSLog(@"sign = %@",sign);
}

- (NSString *)getSignStr {
    int valid_durtion = 10000;
    long int current_time = [[NSDate date] timeIntervalSince1970];
    long int expire_time = current_time + valid_durtion;
    long random = abs(arc4random() % 100000000000);
    NSString* str = [NSString stringWithFormat:@"a=%@&b=%ld&c=%ld&d=%ld", api_key, expire_time, current_time, random];
    NSData* sign_tmp = [self hmac_sha1:api_secret text:str];
    NSData* sign_raw_data = [str dataUsingEncoding:NSUTF8StringEncoding];
    NSMutableData* data = [[NSMutableData alloc] initWithData:sign_tmp];
    [data appendData:sign_raw_data];
    NSString* sign = [data base64EncodedStringWithOptions:0];
    return sign;
}
- (NSData *)hmac_sha1:(NSString *)key text:(NSString *)text{
    const char *cKey  = [key cStringUsingEncoding:NSUTF8StringEncoding];
    const char *cData = [text cStringUsingEncoding:NSUTF8StringEncoding];
    char cHMAC[CC_SHA1_DIGEST_LENGTH];
    CCHmac(kCCHmacAlgSHA1, cKey, strlen(cKey), cData, strlen(cData), cHMAC);
    
    NSData *HMAC = [[NSData alloc] initWithBytes:cHMAC length:sizeof(cHMAC)];
    return HMAC;
}

@end

PHP demo code

<?php
 
function gen_sign($apiKey, $apiSecret, $expired){
    $rdm = rand();
    $current_time = time();
    $expired_time = $current_time + $expired;
    $srcStr = "a=%s&b=%d&c=%d&d=%d";
    $srcStr = sprintf($srcStr, $apiKey, $expired_time, $current_time, $rdm);
    $sign = base64_encode(hash_hmac('SHA1', $srcStr, $apiSecret, true).$srcStr);
    return $sign;
}