SendLabel API Docs
SendLabel API 文档(对接 ERP / WMS)
把冗长说明重组为更清晰的文档页:先判断接入方式,再看关键端点、执行模式、兼容接口和示例请求。
接入方式
统一 API + 兼容 API
执行模式
validate / dry_run / production
交付能力
PDF + tracking + cancel
目标系统
ERP / WMS / OMS
对接总览
先确认基地址、鉴权方式和兼容层路径,实施时会少很多往返沟通。
站点基地址
https://www.sendlabel.de
所有接口都从这个域名展开。
OpenAPI
https://www.sendlabel.de/openapi.json
机器可读规范,适合导入 Postman、Insomnia 或代码生成工具。
统一 API
https://www.sendlabel.de/api/v1
新接入客户优先使用。
DHL 兼容基路径
https://www.sendlabel.de/api/compat/dhl-parcel-de
同时包含更接近原生的 `/orders /labels /manifests /pickup` 镜像,以及 `/v1/*` 资源别名。
UPS 兼容基路径
https://www.sendlabel.de/api/compat/ups
同时包含原生风格的 `/security /shipments /track /rating /pickup` 镜像,以及 `/v1/*` 资源别名。
- - 鉴权支持:Authorization: Bearer <API_KEY> / X-API-Key / Basic(base64(prefix:key)) / dhl-api-key / x-ibm-client-id + x-ibm-client-secret
- - 每个 API Key 还自动支持 sendlabel_<API_KEY_PREFIX> / ups_<API_KEY_PREFIX> / dhl_<API_KEY_PREFIX> 这类虚拟原生 client_id 别名。
- - 如果已有原生 DHL / UPS 客户端,优先看 compat;如果是新项目,优先看 /api/v1。
- - 兼容层错误响应现在采用双轨结构:保留 DHL / UPS 风格字段,同时附加统一的 `sendlabelError`,方便 ERP / WMS 统一解析。
先决定走哪条接口线
这是新版页面最重要的入口,避免实施人员在长页面里迷路。
新项目 / 新接口
优先使用 /api/v1。字段更统一、错误结构更一致、后续维护成本更低。
已有 ERP / WMS 原生 DHL / UPS 对接
优先使用 /api/compat/{provider}/v1,尽量只替换基地址与鉴权。
快速开始
按这个顺序做,最少步骤就能完成第一次 dry run 联调。
- 1. 管理员在 /admin/api-keys 创建 API Key,并配置正确 scope。
- 2. 可选:先创建 sender,并设置默认发件人。
- 3. 先用 validate_only 或 dry_run 调试 /api/v1/shipments/import。
- 4. 再轮询 /api/v1/jobs 或读取 /api/v1/orders/{orderId}。
客户 API 自测
客户登录后可以在 `/profile/api` 直接测试自己的 JSON,而不必先写完整程序。这个入口现在同时支持 SendLabel Unified、DHL Compat 和 UPS Compat。
- - SendLabel Unified:适合测试我们自己的通用 API,请直接粘贴 `/api/v1/shipments/import` 的 JSON。
- - DHL / UPS Compat:适合已有原生客户端的客户,既可用默认样例,也可替换成自己的真实 payload。
- - SendLabel Unified 自测目前建议使用 `validate_only` 或 `dry_run`;受控 `live test` 仍保留给 DHL / UPS compat。
统一 API 自测请求示意
POST /api/profile/api-validator
Content-Type: application/json
{
"token": "slk_xxx",
"suite": "sendlabel_unified_v1",
"scenario": "import_address_review",
"executionMode": "dry_run",
"requestPayload": {
"carrier": "DHL_PARCEL_DE",
"labelPrintFormat": "A4",
"buyerType": "b2c",
"sender": {
"name": "SendLabel Demo GmbH",
"street1": "Lindenstr. 5",
"postalCode": "70173",
"city": "Stuttgart",
"countryCode": "DE"
},
"shipments": [
{
"reference": "ERP-SELF-TEST-001",
"recipient": {
"name": "Max Mustermann",
"street1": "Lindenstr. 5, 1.OG links, c/o Mann",
"postalCode": "70173",
"city": "Stuttgart",
"countryCode": "DE"
},
"parcel": { "weightKg": 1.2, "lengthCm": 30, "widthCm": 20, "heightCm": 10 }
}
]
}
}执行模式与安全边界
企业客户建议把 validate_only、dry_run、production 明确接成三个联调阶段。
validate_only
只校验,不落单、不扣费、不入队。
dry_run
返回预计动作和预计价格,不产生真实业务副作用。
production
正式执行,会进入真实订单、付款与出单链路。
- - 执行模式可通过请求头 X-SendLabel-Execution-Mode 或 body.executionMode 指定。
- - 建议对 import / cancel 相关 POST 接口统一传 Idempotency-Key。
- - 24 小时内同一 API Key + 同一 Idempotency-Key + 同一请求体会直接返回首次结果。
- - 统一 import 与 UPS compat import 当前都按每个 API Key 每 60 秒最多 300 次请求限流;超限会返回 429,并带 Retry-After 响应头。
- - 虽然单次请求最多支持 1000 票,但更建议按每批 50-200 票接入,便于重试、排错和控制单次波动。
- - 轮询 /api/v1/jobs 建议间隔 2-5 秒;该接口同样会返回 429 + Retry-After,如果收到节流,建议按 2s -> 5s -> 10s 退避。
统一错误结构示例
{
"ok": false,
"error": {
"code": "rate_limited",
"message": "Too many requests. Please retry later.",
"details": {
"retryAfterSeconds": 31,
"limit": 300,
"windowSeconds": 60
}
}
}统一接口(推荐新接入)
统一 API 更像产品化接口,适合新客户、新项目和自研中台。
地址簿与基础资料
GET
/api/v1/senders
读取发件人列表。
POST
/api/v1/senders
创建发件人地址。
POST
/api/v1/senders/default
设置默认发件人。
主出单流程
POST
/api/v1/shipments/import
批量导入、校验并触发出单。
GET
/api/v1/jobs?ids=job_1,job_2
轮询异步任务状态。
GET
/api/v1/orders/{orderId}
读取订单、标签摘要和 tracking 概况。
GET
/api/v1/labels?orderId={orderId}
直接下载标签 PDF。
GET
/api/v1/orders/{orderId}/tracking
查询 tracking;DHL 支持 ?refresh=now。
POST
/api/v1/orders/{orderId}/cancel
远程取消面单,需要 cancel:write。
兼容接口(适合已有原生客户端)
把长列表改成按承运人分组的卡片,实施人员更容易找到自己关心的入口。
DHL Parcel DE / Pickup 兼容层
https://www.sendlabel.de/api/compat/dhl-parcel-de/v1/*
资源别名:覆盖 senders / shipments/import / jobs / orders / tracking / cancel / labels,便于旧系统逐步切到统一资源模型。
https://www.sendlabel.de/api/compat/dhl-parcel-de/orders
接收 DHL 原生 POST /orders 风格请求。
https://www.sendlabel.de/api/compat/dhl-parcel-de/orders?validate=true
仅校验地址和数据,不创建真实 shipment。
https://www.sendlabel.de/api/compat/dhl-parcel-de/labels?shipment={shipmentNumber}
按运单号直接返回 PDF。
https://www.sendlabel.de/api/compat/dhl-parcel-de/manifests
支持 manifest / closeout 创建与查询。
https://www.sendlabel.de/api/compat/dhl-parcel-de/pickup/v3/orders
创建 pickup 并自动映射内部订单。
https://www.sendlabel.de/api/compat/dhl-parcel-de/pickup/v3/orders/{pickupId}
取消 pickup 并闭环退款。
UPS 兼容层
https://www.sendlabel.de/api/compat/ups/v1/*
资源别名:覆盖 senders / shipments/import / jobs / orders / tracking / cancel / labels,适合逐步迁移到统一资源模型。
https://www.sendlabel.de/api/compat/ups/security/v1/oauth/token
用 API Key 前缀和完整 Key 获取 access_token。
https://www.sendlabel.de/api/compat/ups/v1/shipments/import
用统一 JSON 结构批量导入 UPS shipment,并在成功时立即返回 label/tracking。
https://www.sendlabel.de/api/compat/ups/shipments/v1/ship
接收原生 ShipmentRequest 并同步创建 shipment。
https://www.sendlabel.de/api/compat/ups/shipments/v1/labels/{shipmentIdentificationNumber}
按 tracking number 直接返回 PDF。
https://www.sendlabel.de/api/compat/ups/shipments/v1/void/cancel/{shipmentIdentificationNumber}
直接按 tracking number 作废 UPS shipment。
https://www.sendlabel.de/api/compat/ups/track/v1/details/{inquiryNumber}
UPS tracking 风格查询。
https://www.sendlabel.de/api/compat/ups/rating/v1/Shop
返回多服务报价。
UPS 包裹单 API 接入
如果客户的目标是通过我们的 API 正式创建 UPS 包裹单,建议直接按下面两条线路之一接入:新系统优先统一接口,已有 UPS 原生客户端优先 compat。
UPS 接入建议
- - 新接入客户:优先使用 `/api/v1/shipments/import`,请求体更简洁,统一错误结构也更稳定。
- - 已有 UPS 原生接口代码:优先使用 `/api/compat/ups/...`,通常只需要替换基地址和鉴权。
- - 正式出单前先用 `validate_only` 或 `dry_run` 联调,确认地址拆分、服务代码和 scope 都正确。
- - 正式环境需要 API Key 具备 `shipments:import` 和 `mode:production`;如需远程取消,还要加 `cancel:write`。
- - 如果客户计划高频批量调用,先按每个 API Key 每分钟 300 次规划客户端节流,并读取 Retry-After 自动退避。
方式一:统一接口创建 UPS 包裹单
这是推荐给新客户的方式。创建成功后可从 `results[].orderId / jobId` 继续查询订单、任务和标签。
curl -X POST "https://www.sendlabel.de/api/v1/shipments/import" \
-H "Authorization: Bearer <API_KEY>" \
-H "X-SendLabel-Execution-Mode: production" \
-H "Idempotency-Key: ups-erp-2026-0001" \
-H "Content-Type: application/json" \
-d '{
"carrier": "UPS",
"labelPrintFormat": "A4",
"senderId": "addr_sender_default",
"shipments": [
{
"reference": "UPS-ERP-0001",
"recipient": {
"name": "Erika Mustermann",
"company": "Muster GmbH",
"street1": "Lindenstr. 5",
"postalCode": "70173",
"city": "Stuttgart",
"countryCode": "DE",
"email": "erika@example.com",
"phone": "+49 151 23456789"
},
"parcel": {
"weightKg": 1.5,
"lengthCm": 30,
"widthCm": 20,
"heightCm": 10
}
}
]
}'方式二:UPS compat 鉴权示例
如果客户已有 UPS OAuth 风格客户端,可先通过镜像 token 路由换取短期 Bearer token。`client_id` 建议使用 `ups_<API_KEY_PREFIX>`,`client_secret` 使用完整 API Key。
curl -X POST "https://www.sendlabel.de/api/compat/ups/security/v1/oauth/token" \
-u "ups_<API_KEY_PREFIX>:<API_KEY>" \
-H "Content-Type: application/x-www-form-urlencoded" \
--data "grant_type=client_credentials"方式二:UPS compat import 示例
如果客户已经适配了我们的 UPS compat import JSON 格式,这个入口现在也会在 UPS 成功出单后立即返回完整 label / tracking,再异步完成账务结算。
curl -X POST "https://www.sendlabel.de/api/compat/ups/v1/shipments/import" \
-H "Authorization: Bearer <API_KEY>" \
-H "X-SendLabel-Execution-Mode: production" \
-H "Idempotency-Key: ups-compat-import-2026-0001" \
-H "Content-Type: application/json" \
-d '{
"carrier": "UPS",
"labelPrintFormat": "A4",
"senderId": "addr_sender_default",
"shipments": [
{
"reference": "UPS-COMPAT-0001",
"recipient": {
"name": "Erika Mustermann",
"company": "Muster GmbH",
"street1": "Lindenstr. 5",
"postalCode": "70173",
"city": "Stuttgart",
"countryCode": "DE",
"email": "erika@example.com",
"phone": "+49 151 23456789"
},
"parcel": {
"weightKg": 1.5,
"lengthCm": 30,
"widthCm": 20,
"heightCm": 10
}
}
]
}'UPS compat 出单示例
这个入口接受 UPS `ShipmentRequest` 风格请求,并在响应里附带 `ShipmentResponse.Compatibility`,方便回读内部 `orderId`、`labelUrl` 和地址校验信息。
curl -X POST "https://www.sendlabel.de/api/compat/ups/shipments/v1/ship" \
-H "Authorization: Bearer <UPS_COMPAT_ACCESS_TOKEN>" \
-H "X-SendLabel-Execution-Mode: production" \
-H "Idempotency-Key: ups-native-2026-0001" \
-H "Content-Type: application/json" \
-d '{
"ShipmentRequest": {
"Shipment": {
"Shipper": {
"Name": "SendLabel Demo GmbH",
"AttentionName": "Warehouse Team",
"Phone": { "Number": "+497111234567" },
"Address": {
"AddressLine": ["Lindenstr. 5"],
"PostalCode": "70173",
"City": "Stuttgart",
"CountryCode": "DE"
}
},
"ShipFrom": {
"Name": "SendLabel Demo GmbH",
"AttentionName": "Warehouse Team",
"Phone": { "Number": "+497111234567" },
"Address": {
"AddressLine": ["Lindenstr. 5"],
"PostalCode": "70173",
"City": "Stuttgart",
"CountryCode": "DE"
}
},
"ShipTo": {
"Name": "Erika Mustermann",
"AttentionName": "Erika Mustermann",
"Phone": { "Number": "+4915123456789" },
"Address": {
"AddressLine": ["Lindenstr. 5"],
"PostalCode": "70173",
"City": "Stuttgart",
"CountryCode": "DE"
}
},
"Service": { "Code": "11" },
"Package": [{
"PackagingType": { "Code": "02" },
"PackageWeight": { "Weight": "1.5" },
"Dimensions": { "Length": "30", "Width": "20", "Height": "10" }
}]
},
"LabelSpecification": {
"LabelImageFormat": { "Code": "PDF" }
}
}
}'成功响应与异步结算字段
统一 UPS import 成功响应
{
"ok": true,
"created": 1,
"total": 1,
"executionMode": "production",
"sideEffectsSuppressed": false,
"results": [
{
"index": 0,
"reference": "UPS-ERP-0001",
"ok": true,
"orderId": "ord_ups_20260001",
"jobId": "job_settlement_20260001",
"jobType": "api_async_settlement",
"trackingNumber": "1Z12345E0205271688",
"labelUrl": "https://www.sendlabel.de/api/v1/labels?orderId=ord_ups_20260001",
"asyncSettlement": {
"status": "pending",
"jobId": "job_settlement_20260001"
},
"notes": [
"UPS shipment created successfully. Billing settlement continues asynchronously in the background."
]
}
]
}UPS compat import 成功响应
{
"ok": true,
"created": 1,
"total": 1,
"executionMode": "production",
"sideEffectsSuppressed": false,
"results": [
{
"index": 0,
"reference": "UPS-COMPAT-0001",
"ok": true,
"orderId": "ord_ups_20260002",
"jobId": "job_settlement_20260002",
"jobType": "api_async_settlement",
"trackingNumber": "1Z12345E0205271689",
"labelUrl": "https://www.sendlabel.de/api/compat/ups/v1/labels?orderId=ord_ups_20260002",
"asyncSettlement": {
"status": "pending",
"jobId": "job_settlement_20260002"
},
"notes": [
"UPS shipment created successfully. Billing settlement continues asynchronously in the background."
]
}
]
}- - `results[].trackingNumber` 和 `results[].labelUrl` 表示 UPS 已经成功出单,客户端可以立即展示或下载标签。
- - `results[].asyncSettlement.status = pending` 表示本地扣费 / 信用额度扣减会在后台继续执行。
- - 如果异步结算最终失败,系统会自动重试、多次失败后触发邮件告警,并自动尝试 void 这张 UPS 面单。
UPS 出单后的常用接口
- - 统一接口出单后:`GET /api/v1/jobs?ids=<jobId>` 轮询任务状态。
- - 读取订单详情:`GET /api/v1/orders/{orderId}`;UPS compat 客户也可使用 `GET /api/compat/ups/v1/orders/{orderId}`。
- - 下载标签 PDF:`GET /api/v1/labels?orderId={orderId}`,或 UPS compat 的 `GET /api/compat/ups/v1/labels?orderId={orderId}`。
- - 查询 tracking:`GET /api/v1/orders/{orderId}/tracking`,或 `GET /api/compat/ups/v1/orders/{orderId}/tracking`。
- - 远程取消 UPS 面单:`POST /api/v1/orders/{orderId}/cancel`,或按运单号调用 `DELETE /api/compat/ups/shipments/v1/void/cancel/{shipmentIdentificationNumber}`。
承运人与地址处理
这一段保留核心业务规则,但用卡片和短句表达,避免一整屏连续段落。
承运人与服务
- - DHL_PARCEL_DE:DHL Paket(德国境内 / 欧盟)
- - DHL_KLEINPAKET:DHL Kleinpaket(仅 DE,<= 1 kg)
- - DP_INTL:Deutsche Post International(德国发国际,非欧盟)
- - UPS 建议优先使用 compat 路由,尤其适合已有原生 UPS 客户端的系统。
地址校验与拆分
- - 系统会在 DHL 正式出单前调用 validate,并尽量返回字段级错误。
- - 如果错误包含 Leitcode,通常意味着邮编、城市、街道和门牌号之间存在不一致。
- - 系统会尝试把 street1 拆分为 streetName + streetNo + addressExtra,例如 Lindenstr. 5, 1.OG links, c/o Mann。
- - UPS compat 入口也会复用同样的地址拆分逻辑,避免把 c/o、楼层、门铃等信息塞进主街道字段。
示例请求与响应
把最常用的 dry_run 请求和标准返回结构放在一起,便于实施人员直接复制。
请求示例:dry_run 导入并报价
curl -X POST "https://www.sendlabel.de/api/v1/shipments/import" \
-H "Authorization: Bearer <API_KEY>" \
-H "X-SendLabel-Execution-Mode: dry_run" \
-H "Idempotency-Key: erp-2026-0001" \
-H "Content-Type: application/json" \
-d '{
"carrier": "DHL_PARCEL_DE",
"labelPrintFormat": "A4",
"buyerType": "b2b",
"shipments": [
{
"reference": "ERP-0001",
"recipient": {
"name": "Max Mustermann",
"street1": "Dingelberg 18",
"postalCode": "38444",
"city": "Wolfsburg",
"countryCode": "DE",
"email": "max@example.com",
"phone": "+49 176 23414739"
},
"parcel": { "weightKg": 1.8, "lengthCm": 30, "widthCm": 20, "heightCm": 10 }
}
]
}'响应示例:标准返回结构
{
"ok": true,
"created": 0,
"total": 1,
"executionMode": "dry_run",
"sideEffectsSuppressed": true,
"results": [
{
"index": 0,
"reference": "ERP-0001",
"ok": true,
"simulated": true,
"wouldCreateShipment": true,
"estimatedAmount": { "currency": "EUR", "amount": 6.23 },
"notes": ["Dry run completed. No order, label, payment, or queue job was created."]
}
]
}- - 进入 production 后,results[] 中通常会出现 orderId 和 jobId。
- - UPS dry_run 还可能返回 estimatedService;地址拆分置信度低时,响应里还可能出现 notes 和 addressReview。
- - labelPrintFormat 常见值:A4、A5、910-300-600、100x70mm。
订单生命周期与 Webhook
把查询、取消、Webhook 和签名规则放在一个区域,减少跳读。
订单与取消
- - GET /api/v1/orders/{orderId}:返回订单详情、标签摘要、tracking 快照和公开 tracking URL。
- - GET /api/v1/orders/{orderId}/tracking:读取 tracking;DHL 支持 ?refresh=now 实时刷新。
- - POST /api/v1/orders/{orderId}/cancel:发起远程取消,API Key 需具备 cancel:write。
Webhook
- - Webhook 在后台 API Key 配置中设置 URL、事件列表和共享 secret。
- - 支持事件:order.created、order.cancelled、label.created、tracking.updated。
- - 请求头:x-sendlabel-event、x-sendlabel-timestamp、x-sendlabel-signature。
- - 验签公式:HMAC_SHA256(webhookSecret, timestamp + '.' + rawBody)。
- - Webhook 通过后台 jobs 异步投递,失败会自动重试。
网页端批量导入
给非 API 客户一个清晰入口,避免他们误以为 API 是唯一方式。
- - 在“创建包裹单”页面使用“批量导入(Excel)”。
- - 系统会读取第一个工作表并把数据加入购物车,再统一支付和出单。