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::
|
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.)
|
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.
|
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;
}