服务地址
生产域名:https://bd.docktea.com
本地调试:http://127.0.0.1:8000
接口列表
GET/health健康检查
GET/测试 UI(当前页面)
GET/docsSwagger 自动文档
POST/ocr单图识别(无鉴权,仅调试)
POST/ocr/batch批量识别(无鉴权,仅调试)
POST/v1/ocr单图识别(生产)需 API Key
POST/v1/ocr/batch批量识别(生产)需 API Key
认证方式
在 HTTP 请求头中传入:
X-API-Key: your_api_key
若服务端未配置 OCR_API_KEY 环境变量,所有请求自动放行(本地开发)。
支持文档类型
| document_type | 中文名 | 页面 (document_side) |
id_card | 身份证 | front / back |
vehicle_license | 行驶证 | home_page / sub_page / both |
driving_license | 驾驶证 | home_page / sub_page / both |
business_license | 营业执照 | single |
vehicle_cert | 车辆合格证 | single |
图片要求
| 项目 | 说明 |
| 格式 | .jpg .jpeg .png .bmp .webp |
| 大小 | 建议 ≤ 5 MB,Nginx 限制 15 MB |
| 分辨率 | 自动缩放到长边 ≤ 960px |
| 耗时 | 首次约 10~30s(模型加载),后续 2~5s |
单图识别
curl -X POST "https://bd.docktea.com/v1/ocr" \
-H "X-API-Key: your_api_key" \
-F "file=@/path/to/id_card.jpg" \
-F "backend=auto" \
-F "slow_mode=false"
批量识别
curl -X POST "https://bd.docktea.com/v1/ocr/batch" \
-H "X-API-Key: your_api_key" \
-F "files=@front.jpg" \
-F "files=@back.jpg"
健康检查
curl "https://bd.docktea.com/health"
import requests
API_URL = "https://bd.docktea.com/v1/ocr"
API_KEY = "your_api_key"
with open("id_card.jpg", "rb") as f:
resp = requests.post(
API_URL,
headers={"X-API-Key": API_KEY},
files={"file": ("id_card.jpg", f, "image/jpeg")},
data={"backend": "auto", "slow_mode": "false"},
timeout=60,
)
resp.raise_for_status()
data = resp.json()
print("类型:", data["document_type"])
print("通过:", data["pass_for_insurance"])
print("字段:", data["fields"])
批量
import requests
files = [
("files", ("front.jpg", open("front.jpg","rb"), "image/jpeg")),
("files", ("back.jpg", open("back.jpg", "rb"), "image/jpeg")),
]
resp = requests.post(
"https://bd.docktea.com/v1/ocr/batch",
headers={"X-API-Key": "your_api_key"},
files=files,
timeout=120,
)
for item in resp.json():
print(item["image"], "->", item["document_type"],
"pass:", item["pass_for_insurance"])
// 单图(浏览器 File 对象)
async function ocrSingle(file, apiKey) {
const form = new FormData();
form.append("file", file);
form.append("backend", "auto");
const resp = await fetch("https://bd.docktea.com/v1/ocr", {
method: "POST",
headers: { "X-API-Key": apiKey },
body: form,
});
if (!resp.ok) throw new Error(`HTTP ${resp.status}`);
return resp.json();
}
// 批量
async function ocrBatch(files, apiKey) {
const form = new FormData();
for (const f of files) form.append("files", f);
const resp = await fetch("https://bd.docktea.com/v1/ocr/batch", {
method: "POST",
headers: { "X-API-Key": apiKey },
body: form,
});
if (!resp.ok) throw new Error(`HTTP ${resp.status}`);
return resp.json(); // 返回数组
}
<?php
$url = 'https://bd.docktea.com/v1/ocr';
$apiKey = 'your_api_key';
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => ["X-API-Key: $apiKey"],
CURLOPT_POSTFIELDS => [
'file' => new CURLFile('/path/to/id.jpg', 'image/jpeg'),
'backend' => 'auto',
],
CURLOPT_TIMEOUT => 60,
]);
$body = curl_exec($ch);
curl_close($ch);
$data = json_decode($body, true);
echo $data['document_type'] . "\n";
print_r($data['fields']);
请求参数(multipart/form-data)
| 字段 | 类型 | 必填 | 默认 | 说明 |
file | File | 是 | — | 单图接口;支持 jpg/png/bmp/webp |
files | File[] | 是 | — | 批量接口;同名字段重复传 |
backend | string | 否 | auto | auto / paddle |
model_source | string | 否 | auto | auto / online / offline |
slow_mode | bool | 否 | false | true 启用高精度(更慢) |
响应结构(JSON)
{
"image": "filename.jpg", // 上传文件名
"document_type": "id_card", // 文档类型
"document_side": "front", // 页面:front/back/home_page/sub_page/single/both
"confidence": 0.95, // 置信度 0~1
"quality": "high", // 图像质量:high/medium/low
"pass_for_insurance": true, // 是否通过保险业务校验
"missing_fields": [], // 缺失的必填字段
"required_fields": ["name","idNumber","birthDate"],
"review_reason": "", // 不通过原因
"retry_attempted": false, // 是否触发二次宽松识别
"retry_filled": [], // 二次识别补全的字段
"fields": { ... }, // 结构化字段(见字段说明)
"engine": "paddleocr", // 实际引擎:paddleocr | qwen_vl
"elapsed_ms": 1230, // 耗时 ms
"error": null // 错误信息(正常为 null)
}
双面合图(document_side == "both")
当单张图片同时包含行驶证/驾驶证正副两页时,顶层额外返回 pages 数组,每个元素结构与普通响应相同(含 fields、missing_fields 等)。
{
"document_type": "vehicle_license",
"document_side": "both",
"pass_for_insurance": true,
"pages": [
{ "document_side": "home_page", "fields": { "licensePlateNumber": "京A12345", ... } },
{ "document_side": "sub_page", "fields": { "inspectionRecord": "2026-06", ... } }
]
}
HTTP 状态码
| 状态码 | 含义 | 常见原因 |
| 200 | 成功 | — |
| 400 | 请求错误 | 格式不支持 / 空文件 / 未传文件 |
| 401 | 认证失败 | X-API-Key 缺失或错误 |
| 429 | 服务繁忙 | 并发请求等待超时(默认 30s) |
| 500 | 服务器错误 | 响应体含 error 字段 |
阿里云OCR对比接口 POST /ali_ocr
测试页内部调用,用于自动对比阿里云识别结果。优先级:① 实时API → ② 离线样本库(ali_static_results.json)。
| 参数 | 类型 | 说明 |
file | File | 与子墨OCR相同的图片 |
doc_type | string | id_card / vehicle_license / driving_license / business_license / vehicle_cert |
our_fields | string | 子墨OCR识别结果 fields JSON(用于离线库匹配) |
{
"status": "ok", // ok / no_credentials / sdk_missing / error
"doc_type": "id_card",
"ali_fields": { ... }, // 阿里云识别结果字段
"source": "api" // api(实时)或 static(离线样本)
}
兜底策略说明
子墨IDOCR识别 通过(pass_for_insurance=true)→ 直接使用子墨结果,不注入阿里云值。
子墨IDOCR识别 不通过 → 阿里云识别到的字段以蓝色「兜底」标注显示在子墨字段解析区。
阿里云结果优先来自实时API,其次使用本地离线样本库(ali_static_results.json),两者都不可用时提示配置。
身份证
行驶证
驾驶证
营业执照
车辆合格证
| 字段名 | 中文 | 页面 | 必填 |
| name | 姓名 | front | 是 |
| idNumber | 身份证号码 | front | 是 |
| birthDate | 出生日期 | front | 是 |
| sex | 性别 | front | |
| ethnicity | 民族 | front | |
| address | 住址 | front | |
| issueAuthority | 签发机关 | back | |
| validPeriod | 有效期限 | back | |
| 字段名 | 中文 | 页面 | 必填 |
| licensePlateNumber | 号牌号码 | home_page | 是 |
| vinCode | 车辆识别代码(VIN) | home_page | 是 |
| owner | 所有人 | home_page | 是 |
| vehicleType | 车辆类型 | home_page | |
| useNature | 使用性质 | home_page | |
| model | 品牌型号 | home_page | |
| engineNumber | 发动机号码 | home_page | |
| registrationDate | 注册日期 | home_page | |
| issueDate | 发证日期 | home_page | |
| address | 住址 | home_page | |
| licensePlateNumber | 号牌号码 | sub_page | 是 |
| inspectionRecord | 检验有效期 | sub_page | 是 |
| passengerCapacity | 核定载人数 | sub_page | |
| totalWeight | 总质量 | sub_page | |
| curbWeight | 整备质量 | sub_page | |
| overallDimension | 外廓尺寸 | sub_page | |
| 字段名 | 中文 | 页面 | 必填 |
| licenseNumber | 证号 | home_page | 是 |
| name | 姓名 | home_page | 是 |
| drivingClass | 准驾车型 | home_page | 是 |
| sex | 性别 | home_page | |
| nationality | 国籍 | home_page | |
| birthDate | 出生日期 | home_page | |
| firstIssueDate | 初次领证日期 | home_page | |
| validFrom | 有效期起 | home_page | |
| validTo | 有效期至 | home_page | |
| licenseNumber | 证号 | sub_page | 是 |
| archiveNumber | 档案编号 | sub_page | |
| 字段名 | 中文 | 必填 |
| creditCode | 统一社会信用代码(18位) | 是 |
| companyName | 营业名称 | 是 |
| legalPerson | 法定代表人 | 是 |
| companyType | 类型 | |
| registeredCapital | 注册资本 | |
| registrationDate | 成立日期 | |
| validFromDate | 营业期限起 | |
| validToDate | 营业期限止 | |
| businessAddress | 住所 | |
| businessScope | 经营范围 | |
| issueDate | 发照日期 | |
| 字段名 | 中文 | 必填 |
| vinCode | 车辆识别代号(VIN) | 是 |
| certificateNumber | 合格证编号 | 是 |
| vehicleName | 车辆名称 | |
| vehicleModel | 车辆型号 | |
| vehicleColor | 车身颜色 | |
| engineNumber | 发动机号 | |
| fuelType | 燃料种类 | |
| displacement | 排量(mL) | |
| power | 功率(kW) | |
| emissionStandard | 排放标准 | |
| totalWeight | 总质量(kg) | |
| overallDimension | 外廓尺寸(mm) | |
| vinCode | VIN | |
| manufactureName | 制造企业 | |
| manufactureDate | 制造日期 | |
| issueDate | 发证日期 | |