面向货代与跨境物流场景的 AI 识别服务。覆盖 DHL / UPS / FedEx 等多渠道商业发票与运单图片的结构化识别。
http://localhost:5102 测试。对外 API Key 只可调用识别主接口,必须携带 X-API-Key 请求头。浏览器端在线识别使用登录 Cookie 会话。
| 方式 | 说明 |
|---|---|
X-API-Key: hinv_xxxxx | API 密钥,仅创建时显示一次。请妥善保管。 |
Cookie hinv_session | 网页登录后由服务端设置;HttpOnly + SameSite=Lax。 |
Saas:CostPerRecognition 调整)。Saas:InitialCredits)。402 Payment Required。上传发票或运单图片,返回 SSE 流式响应,包含处理阶段进度与最终结构化结果。
| Header | 必填 | 说明 |
|---|---|---|
X-API-Key | 是 | API 密钥(hinv_ 前缀) |
Content-Type | 是 | multipart/form-data; boundary=... |
| Query | 必填 | 说明 |
|---|---|---|
channel | 否 | 通道类型:DHL / UPS / FED,留空则自动判断 |
| Form | 必填 | 说明 |
|---|---|---|
file | 是 | 二进制图片,PNG / JPEG / WebP,建议 < 8MB |
event: data
data: {"stage":"preprocess","message":"方向纠正完成"}
data: {"stage":"crop","regions":["sender","recipient","items"]}
data: {"stage":"extract","progress":"sender ok"}
data: {"result":{
"sender": {"name":"...","address":"..."},
"recipient": {"name":"...","address":"..."},
"items": [{"description":"...","quantity":1,"unitPrice":10,"subTotal":10}],
"cargoValue": {"totalValue":10,"currency":"USD"},
"logistics": {"trackingNumber":"...","weight":"..."}
}}
curl -N -X POST "https://your-host/recognize-agent-channel-stream?channel=DHL" \
-H "X-API-Key: hinv_xxxxxxxxxxxx" \
-F "file=@invoice.jpg"
| 状态码 | 说明 |
|---|---|
| 200 | 成功(流中 result 即为最终结构化结果) |
| 400 | 请求体不合法,如缺少 file |
| 401 | 缺少或无效的 X-API-Key |
| 402 | 积分余额不足 |
| 500 | 识别内部错误(流中以 error 事件返回) |
用户自助注册。成功自动登录并设置会话 Cookie。
curl -X POST https://your-host/api/saas/auth/register \
-H "Content-Type: application/json" \
-d '{"email":"user@example.com","password":"至少8位密码","displayName":"可选"}'
邮箱密码登录。
登出并清空会话。
返回当前登录用户信息(id / email / role / creditBalance 等)。
列出当前登录用户全部密钥(不含明文)。
创建密钥。明文仅在响应里返回一次,务必保存。
curl -X POST https://your-host/api/saas/keys \
-H "X-API-Key: hinv_xxxx" \
-H "Content-Type: application/json" \
-d '{"name":"生产环境"}'
启用或停用密钥。请求体 {"enabled":true|false}。
重命名密钥。请求体 {"name":"新名称"}。
硬删除密钥(不可恢复)。
数据看板:积分余额、累计调用、今日调用、有效密钥、7 天每日柱图。
使用日志分页。
| Query | 默认 | 说明 |
|---|---|---|
page | 1 | 页码 |
pageSize | 20 | 每页大小(最大 200) |
status | - | 按状态过滤:success / failed |
endpoint | - | 按接口路径包含子串过滤 |
兑换码兑换积分。请求体 {"code":"fsw_xxxx"}。返回 credits(本次获得)和 creditBalance(当前余额)。
| 状态码 | 含义 |
|---|---|
| 200 | 成功 |
| 400 | 请求参数缺失或格式错误 |
| 401 | 未登录或 API 密钥无效/已吊销/已停用 |
| 402 | 积分余额不足 |
| 403 | 需要管理员权限 |
| 404 | 资源不存在 |
| 409 | 资源冲突(如邮箱已被注册) |
| 500 | 服务器内部错误 |
import requests
API = "https://your-host"
KEY = "hinv_xxxxxxxxxxxx"
with open("invoice.jpg", "rb") as f:
resp = requests.post(
f"{API}/recognize-agent-channel-stream?channel=DHL",
headers={"X-API-Key": KEY},
files={"file": ("invoice.jpg", f, "image/jpeg")},
stream=True,
)
import json
for line in resp.iter_lines():
if line.startswith(b"data:"):
payload = json.loads(line[5:].strip())
if "result" in payload:
print(json.dumps(payload["result"], ensure_ascii=False, indent=2))
const axios = require('axios');
const fs = require('fs');
const API = 'https://your-host';
const KEY = 'hinv_xxxxxxxxxxxx';
const form = new FormData();
form.append('file', fs.createReadStream('invoice.jpg'));
axios.post(`${API}/recognize-agent-channel-stream?channel=DHL`, form, {
headers: { 'X-API-Key': KEY, ...form.getHeaders() },
responseType: 'stream'
}).then(async resp => {
for await (const chunk of resp.data) {
const lines = chunk.toString().split('\n').filter(l => l.startsWith('data:'));
for (const ln of lines) {
const obj = JSON.parse(ln.slice(5).trim());
if (obj.result) console.log(JSON.stringify(obj.result, null, 2));
}
}
});
最后更新于 2026-08 · 泛识物流识别