开发者文档

开放 API 对接指南

签名鉴权、幂等建单、按 Key 限流与出站回调。本页口径与 docs/04-API-DESIGN.md §4(真源 OPENAPI_CONTRACT.md v1.0)一致;机器面 GET /api/open/docs 上线后两处同源。

上手

对接四步

按这四步走通,再上生产。

  1. 01联系中文客服申请 API Key(f8ok_ 前缀,明文只在建钥/换钥响应中出现一次);写端点需运营显式开通 write 作用域。
  2. 02按 §鉴权 拼五段签名串,每个请求带齐 x-f8-key-id / x-f8-timestamp / x-f8-nonce / x-f8-signature 四个头。
  3. 03用 GET 端点(inventory / lots / tracking / billing)打通只读链路,再接 POST 建单(inbounds / outbounds,必带 Idempotency-Key)。
  4. 04上生产前按「限流、幂等与错误码」逐条核对退避与重试策略,出站回调按需向运营登记。

鉴权

凭据与签名

每个请求都要带四个签名头;签名串五段、顺序固定、换行分隔。

凭据格式

f8ok_<keyId>_<secret>(keyId 12 位 hex,secret 64 位 hex,字母表锁 hex)

签名算法

HMAC-SHA256 / base64url

时间窗

±5 分钟(300000ms,超窗 401 timestamp_out_of_window)

重放窗口

24 小时(nonce 去重)

并行可用钥

最多 2 把(active + grace 合计)

轮换宽限

24 小时(不可叠加;宽限届满即 expired)

默认作用域

read(写端点需运营开通 write)

状态机

active → grace → expired;任一状态可即时吊销 → revoked

签名串的拼法(LF = 换行符)

METHOD(大写)
LF
pathWithQuery(查询串原文,不重排不解码)
LF
timestamp(毫秒)
LF
nonce(每请求唯一)
LF
sha256Hex(请求体原文;空体也取 sha256("") 摘要)
请求头说明
请求头必填说明
x-f8-key-id是apiKey 第二段 keyId
x-f8-timestamp是毫秒级 Unix 时间戳字符串
x-f8-nonce是每请求唯一随机串(建议 UUID 或 ≥16 位 base36)
x-f8-signature是签名串的 HMAC-SHA256,base64url 输出

租户不可自证:customerCode 由鉴权层按 keyId 反查注入,请求体与查询串里的同名字段一律忽略。校验链固定:头齐备 → 时间窗 → keyId 存在 → 钥状态 → 可解密 → 签名比对 → nonce 去重 → 频控 → 作用域。

配额

限流、幂等与分页

超限返回 429 并带 Retry-After;幂等防「重签再建一张单」,与防重放是两把闸。

每 Key 默认限流

120 次 / 60 秒(固定窗按 epoch 分钟对齐)

按 Key 可调

运营可按 Key 覆写每分钟配额

幂等头

Idempotency-Key(客户端 UUID,≤64 字符)

幂等保留

24 小时;台账按「一把 Key」隔离

在途可重抢

占位超 5 分钟可被同键重抢;处理器抛错当场释放

分页默认/上限

pageSize 20 / 100;越界 400 invalid_pagination,不静默钳制

单张建单行数

skuLines 1..500

响应头

X-RateLimit-Limit / Remaining / Reset;429 时另带 Retry-After;恒 Cache-Control: no-store

通用响应固定 data + pagination{page,pageSize,total} + requestId;时间 ISO-8601 UTC 带毫秒;金额两位小数、币种恒 GBP。幂等命中也落审计;台账不可用时返回 503 idempotency_unavailable 且本次不执行。

端点

六个端点

六端点注册表;版本在路径(v1 → v2 发布后 v1 保留 6 个月)。库存调整、盘点、账户充值与面单二进制流不开放。

端点注册表
路径方法作用域幂等键说明
/api/open/v1/inboundsPOSTwrite必带入库预报建单,等价门户预报表单
/api/open/v1/outboundsPOSTwrite必带出库下单,只接 skuLines 与收件信息,不参与定价
/api/open/v1/inventoryGETread不适用余额按 SKU/库位分页,含 7+2 桶全列
/api/open/v1/lotsGETread不适用批次与效期,FEFO 可查
/api/open/v1/trackingGETread不适用出库单 + 轨迹事件流 trackingEvents
/api/open/v1/billingGETread不适用账单与费用行,只读不含支付动作

示例

请求与响应

以入库预报建单为例(201 成功回执)。

POST /api/open/v1/inbounds(头 Idempotency-Key: <uuid>)

{
  "contact": "王磊", "phone": "+8613800000000", "eta": "2026-11-04", "transport": "快递",
  "platform": "AMZ", "tracking": "SF1234567890", "service": "FBA 转运", "attribute": "普货",
  "productName": "蓝牙耳机、手机壳",
  "skuLines": [
    { "skuCode": "SKU-001", "productName": "蓝牙耳机黑色款", "expectedQty": 120, "cartonCount": 4 },
    { "skuCode": "SKU-002", "productName": "手机壳透明款", "expectedQty": 300, "cartonCount": 2 }
  ]
}

201 响应

{
  "data": { "id": "IB-261028-0007", "status": "pending_review", "cartons": 6, "skuCount": 2,
            "createdAt": "2026-10-28T02:40:11.004Z" },
  "requestId": "6f0c3a1e-9b47-4d2a-8c1e-2f7a5b3d9c04"
}

排错

错误码

错误体为扁平形状 {error, code, requestId}(对外契约,不套内部嵌套包络)。

鉴权段错误码
HTTPcode处置建议
401missing_signature_headers检查 SDK 是否漏带头(尤其反向代理剥头)
401timestamp_out_of_window校正时钟;不要用缓存时间戳重发旧请求
401unknown_key_id核对 apiKey 前缀与签发环境(测试/生产不同库)
401signature_mismatch核对五段顺序、path 与查询串原文、请求体原文、方法大小写
403key_revoked用剩余钥或申请重签,勿重试
403key_expired切到新钥;旧钥不再可用
403key_unusable服务端主密钥已变更 → 联系运营重签(一次性事件,不重试)
403nonce_replayed每请求生成新 nonce,重试要重新签名
403scope_not_granted走运营开通 write 白名单
429rate_limited按 retryAfterMs 退避,勿并行重试
400 missing_idempotency_key400 invalid_idempotency_key400 invalid_request_body400 unknown_field400 unsupported_field400 unknown_sku(带 skuCodes)400 invalid_sku_lines400 eta_too_early400 invalid_pagination400 invalid_filter405 method_not_allowed409 idempotency_key_conflict409 idempotency_key_in_progress409 customer_credit_blocked(带 creditRisk)500 internal_error(带 errorId)503 idempotency_unavailable

回调

出站 webhook

方向相反、算法相同:仓库主动把单据状态变化推给您,用同一条五段签名串验真(每端点独立 f8wh_ 密钥)。

每客户端点上限

3 个

尝试次数

6 次(退避 1 / 5 / 15 / 60 / 240 / 240 分钟)

投递超时

8 秒;4xx(除 408/429)判 blocked 不再重试

台账保留

7 天、上限 1000 行;at-least-once 语义,按 x-f8-event-id 幂等消费

回调请求头
回调头说明
x-f8-key-id回调端点编号(wh_xxxxxxxx,不是 API Key 编号)
x-f8-timestamp本次尝试的毫秒时间戳(每次重试重新签)
x-f8-nonce本次尝试随机串;接收端去重请按 x-f8-event-id,不要按 nonce 拦重试
x-f8-signatureHMAC-SHA256(webhook_secret, 签名串) 的 base64url
x-f8-event-id事件号=幂等键 outbound:<单号>:<日志号> / inbound:<单号>:<日志号>
x-f8-attempt第几次尝试(1 起)
事件目录
事件类型触发口径
inbound.status_changed入库单状态变化(events 时间线,不截断)
outbound.status_changed出库单状态变化(operationLogs,保留最近 60 条)
outbound.backorder_split欠补拆单事实
outbound.backorder_recheck到货复检结果
outbound.intercept_completed截单完成事实
test.delivery运营点「测试」的手握事件,不参与订阅

push 只说「变了」,pull 才是事实源:轨迹与作业明细请回查 GET /api/open/v1/tracking。作业粒度日志(scan_*、exception_* 等)不推。

开始对接

密钥申请与 write 作用域开通,由运营按客户档案办理。

提交公司 / 店铺信息与对接场景,客服会签发首把 Key 并同步契约版本口径(v1.0,破坏性变更走 /api/open/v2)。

申请对接