API 总入口:POST /api/ocr/{apicode},请求与响应均为 JSON。所有识别接口按次消耗积分。
| 接口编码 | 接口名称 | 接口地址 | 积分/次 | 状态 |
|---|---|---|---|---|
| sfz | 身份证识别 | /api/ocr/sfz | 1 | 已上线 |
| yhk | 银行卡识别 | /api/ocr/yhk | 1 | 已上线 |
| xsz | 行驶证识别 | /api/ocr/xsz | 1 | 已上线 |
| jsz | 驾驶证识别 | /api/ocr/jsz | 1 | 已上线 |
| yyzz | 营业执照识别 | /api/ocr/yyzz | 1 | 已上线 |
| mp | 名片识别 | /api/ocr/mp | 1 | 已上线 |
| jdcdjz | 机动车登记证书识别 | /api/ocr/jdcdjz | 1 | 已上线 |
| 接口编码 | 接口名称 | 接口地址 | 积分/次 | 状态 |
|---|---|---|---|---|
| jzxwx | 集装箱尾箱识别 | /api/ocr/jzxwx | 1 | 已上线 |
每次调用需在请求体 JSON 中携带以下公共参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| SecretId | string | 是 | 调用者身份标识,个人中心获取 |
| timestamp | string | 是 | Unix 秒级时间戳,与服务器时间偏差超过 300 秒将被拒绝 |
| sign | string | 是 | 请求签名,见下文签名算法 |
| image | string | 二选一 | 图片 base64 字符串(可带 data:image/xxx;base64, 前缀) |
| imageUrl | string | 二选一 | 图片 http(s) 访问地址 |
注意:所有参数值一律为字符串;除 sign 外的全部参数(含公共参数与业务参数)均参与签名。
取全部请求参数(sign 除外),按参数名的 ASCII 码字典序升序排序。只按参数名排序,参数值保持对应即可,不参与比较大小。
将排序后的参数拼接为 key1=value1&key2=value2&... 形式(参数名与参数值原样拼接,不做 URL 编码)。
以 SecretKey 作为密钥,对签名原文使用 HMAC-SHA1 算法计算摘要,再对摘要结果做 Base64 编码,得到 sign。
# 伪代码 params = {SecretId, timestamp, 业务参数...} # 不含 sign keys = sort_by_ascii(params.keys()) plain = '&'.join(k + '=' + params[k] for k in keys) sign = base64(hmac_sha1(key=SecretKey, message=plain))
import time, hmac, hashlib, base64, json, requests
SECRET_ID = '你的SecretId'
SECRET_KEY = '你的SecretKey'
def sign(params, secret_key):
items = sorted((k, v) for k, v in params.items() if k != 'sign')
plain = '&'.join(f'{k}={v}' for k, v in items)
return base64.b64encode(hmac.new(secret_key.encode(),
plain.encode(), hashlib.sha1).digest()).decode()
params = {
'SecretId': SECRET_ID,
'timestamp': str(int(time.time())),
'image': 'data:image/jpeg;base64,/9j/4AAQ...' # 图片base64
}
params['sign'] = sign(params, SECRET_KEY)
resp = requests.post('https://ocr.jmdz.online/api/ocr/sfz', json=params)
print(resp.json())
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.util.*;
Map<String, Object> params = new HashMap<>();
params.put("SecretId", "你的SecretId");
params.put("timestamp", String.valueOf(System.currentTimeMillis() / 1000));
params.put("image", "data:image/jpeg;base64,/9j/4AAQ...");
String plain = params.entrySet().stream()
.filter(e -> !"sign".equals(e.getKey()) && e.getValue() != null)
.sorted(Map.Entry.comparingByKey())
.map(e -> e.getKey() + "=" + e.getValue())
.reduce((a, b) -> a + "&" + b).orElse("");
Mac mac = Mac.getInstance("HmacSHA1");
mac.init(new SecretKeySpec(SECRET_KEY.getBytes(StandardCharsets.UTF_8), "HmacSHA1"));
String sign = Base64.getEncoder().encodeToString(mac.doFinal(plain.getBytes(StandardCharsets.UTF_8)));
params.put("sign", sign);
识别成功时返回:
{
"code": 0,
"message": "识别成功",
"data": {
"SecretId": "S-XXXX...",
"timestamp": "20260913223000",
"requestId": "uuid",
"points": 999,
"name": "张三",
"sex": "男",
"idNumber": "350102199001011234",
"sign": "Base64(HMAC-SHA1)" # 响应签名:覆盖 data 中除 sign 外的全部字段
}
}
data 中的业务字段随接口类型不同而不同(身份证:name/sex/nation/birth/address/idNumber/issuedBy/validDate)。响应签名规则与请求一致:将 data 内除 sign 外字段按 ASCII 排序拼接后,用 SecretKey 做 HMAC-SHA1 再 Base64,可与返回值中的 sign 比对,用于校验响应确由本平台返回。
| code | 说明 |
|---|---|
| 0 | 识别成功 |
| 4001 | 积分不足,请先充值 |
| 4002 | 接口未开通 |
| 4003 | 签名校验失败 |
| 4004 | 参数错误(缺少公共参数 / JSON 非法 / 图片无效) |
| 4005 | timestamp 已过期 |
| 4006 | 识别失败 |
| 4007 | 认证失败(SecretId 无效或账号被禁用) |
| 401 | Web 端未登录(仅个人中心接口使用) |
| 500 | 系统繁忙 |