开发文档
v2.2 版本不向下兼容,但您可以继续使用 V1 版本;
未来停用 V1 版本会提前通过客服群、邮件、短信进行告知。您也可以联系在线客服人员(页面右下角)寻求帮助;
介绍
17TRACK API 是一个物流查询接口(以下简称API)。通过 API 可以查询 17TRACK 所支持的 2,100 运输商的物流信息,API 基于 HTTP 协议与开发语言无关,通过 WEBHOOK 机制实现信息传递(先注册单号再推送信息),全程自动跟踪物流信息。17TRACK 支持的运输商请访问这里查看 https://www.17track.net/zh-cn/carriers ;
使用指南
- 请确保您已成功注册了 API 账号,如果还没有请访问这里 https://api.17track.net ;
- 每月可以使用 100 个免费单号;
第一步 定义 WebHook 接口
- WebHook 接口,您可以自行编写,也可以访问 webhook.site 站点,使用免费的 WebHook 接口接收推送进行验证;
- 不管何种方式都需要把 WebHook 接口地址保存在API系统中,这一步需要您先登录,访问 设置页进行操作;
- 关于 WebHook 的定义、设置、测试请参见本文的WebHook使用介绍;
第二步 注册单号
- 您要准备一个物流单号(以下简称单号);
- 使用擅长的开发语言编写请求代码来注册单号,当然使用接口调试工具(如postman、apifox、apipost等)来验证也是可以的;
- API 所有接口只接受带有唯一密钥的请求;
- 以bash命令为例,把 密钥 设置到头信息的 17token 中,单号通过 number 传递(注意,一次请求可以传递 40 个单号);
curl -X POST \ --header '17token:密钥' \ --header 'Content-Type:application/json' \ --data '[ { "number": "RR123456789CN" }, { "number: "21213123123230" } ]' \ https://api.17track.net/track/v2.2/register
- 如响应报文与下方返回的类似,code 是 0,accepted 节点有相关信息,则表示单号注册成功;
{ "code": 0, "data": { "accepted": [ { "origin": 1, "number": "RR123456789CN", "carrier": 3011 } ], "rejected": [ { "number": "21213123123230", "error": { "code": -18019903, "message": "Carrier cannot be detected." } } ] } }
第三步 监听 WebHook 接口,获取推送信息
- 首次,物流单号注册成功后几秒内返回跟踪结果(因网络、运输商服务等问题,可能有 5 分钟以上的延迟);
- 如接收到推送结果如下,则表示自动跟踪到物流信息并推送成功:
{ "event": "TRACKING_UPDATED", "data": { "number": "RR123456789CN", "carrier": 3011, ... ... // 完整内容参考文档中的《更新跟踪通知》 } }
获取密钥
使用 API 账号登录后访问 设置页 获取密钥;
更改密钥
在 设置页 点击 更改密钥 按钮,新密钥生效时间会有最长 5 分钟延迟,新密钥生效后旧密钥立即失效。
注意事项
- 不建议 在网页端使用,有泄露密钥的风险;
- 每个接口请求限制频率为 3req/s,超限会报 429 错误;
- 所有接口响应报文中的时间都是 UTC 格式;
- 所有接口在保持兼容的基础上可能会扩展内容;
- 所有接口响应数据,当各属性没有信息时统一显示为null;
- 物流单号与运输商代码 组合成数据的唯一标识;
自动跟踪
- 首次,物流单号注册成功后几秒内返回跟踪结果(因网络、运输商服务等问题,可能有 5 分钟以上的延迟);
- 后续,按物流主状态每 6~12小时 之间进行 1 次跟踪,异常或妥投包裹每 24 小时进行一次;
- 跟踪时间为起始时间,连续 30 天无事件更新会停止跟踪;
- 系统同步到包裹状态变更为 成功签收 后,再跟踪 15 天,期间无事件更新,则会停止跟踪;
- 停止跟踪的物流单号可以 重启跟踪 1 次;
- 停止跟踪的物流单号会持续保留在当前账号中 90 天,之后会从当前账号中删除;
扣费说明
基础信息
运输商代码
此代码是对应运输商名称的 Key,用于请求各类接口的入参,可以通过以下方式取得:
附加跟踪参数
- 某些运输商需要额外参数才可以跟踪运单变化,请参考以下内容:
运输商名称 | 运输商代码 | 参数类型 | 参数示例 | 是否必填 |
---|---|---|---|---|
Bpost | 2061 | 邮编 | 1000 | 否 |
DHL Paket | 7041 | 邮编 | 1000 AA | 否 |
PostNL | 14041 | 目的地国家 | FR | 是 |
PostNL | 14041 | 邮编 | 1000 AA | 否 |
FedEx | 100003 | 发货日期 | 2024/1/1 | 否 |
GLS | 100005 | 邮编 | 是 | |
GLS (IT) | 100024 | 邮编 | 否 | |
BRT Bartolini(DPD) | 100026 | 邮编 | 1000 AA | 否 |
Colis Prive(Colis Privé) | 100027 | 邮编 | 12345 | 否 |
J&T Express (ID) | 100074 | 手机 | 8888 | 是 |
Caribou | 100078 | 邮编 | 1000 | 否 |
斯里兰卡捷高 | 100155 | 邮编 | 1000 | 否 |
XDP EXPRESS | 100167 | 邮编 | LS27 0BN | 是 |
GLS Spain (National) | 100189 | 邮编 | 123456 | 是 |
GLS (Croatia) | 100207 | 邮编 | 是 | |
J&T Express (TH) | 100271 | 手机 | 8888 | 是 |
GLS (HU) | 100280 | 邮编 | 是 | |
GLS (CZ) | 100281 | 邮编 | 是 | |
GLS (SK) | 100282 | 邮编 | 是 | |
GLS (SI) | 100283 | 邮编 | 是 | |
GLS (RO) | 100284 | 邮编 | 是 | |
Mondial Relay | 100304 | 邮编 | 123456 | 是 |
GLS (PT) | 100316 | 邮编 | 是 | |
DPD (BE) | 100321 | 邮编 | 1000 AA | 否 |
GEODIS | 100356 | 邮编 | 1000 AA | 否 |
Paack | 100364 | 邮编 | 12345 | 是 |
GLS (NL) | 100384 | 邮编 | 12345 | 是 |
J&T Express (MX) | 100388 | 手机 | 8888 | 是 |
Pall-Ex (UK) | 100394 | 邮编 | CO14 8LF | 是 |
GEL Express Logistik | 100396 | 邮编 | 1000 AA | 否 |
Gebrüder Weiss (GW) | 100431 | 邮编/城市/国家/发件人/收件人 | 是 | |
Nacex | 100436 | 邮编 | 1234 | 是 |
Seur | 100438 | 手机 | 8888 | 是 |
Seur | 100438 | 邮编 | 28001 | 是 |
J&T Express (VN) | 100456 | 手机 | 8888 | 是 |
Cycloon (Fietskoeriers) | 100466 | 邮编 | 1000 AA | 是 |
DPD (CZ) | 100483 | 邮编 | 1000 AA | 否 |
DX | 100484 | 邮编 | 12345 | 是 |
Ryder | 100522 | 邮编 | 88888 | 是 |
Tuffnells | 100524 | 邮编 | S27 1BZ | 是 |
Postmedia Parcel Services (BNI Parcel Tracking) | 100552 | 邮编 | H4E 5R4 | 是 |
DPD (AT) | 100556 | 邮编 | 1000 AA | 否 |
Walkers Transport | 100580 | 邮编 | LS27 0BN | 是 |
DPD (HU) | 100584 | 邮编 | 1000 AA | 否 |
InPost (ES) | 100594 | 邮编 | 51900 | 是 |
InPost (PT) | 100598 | 邮编 | 51900 | 是 |
J&T Express (EG) | 100619 | 手机 | 8888 | 是 |
Allied Express Transport | 100623 | 邮编 | 1000 | 是 |
GLS Portugal (National) | 100646 | 邮编 | 1000-205 | 是 |
A TU HORA EXPRESS | 100688 | 邮编 | 1000 | 否 |
J&T Express (BR) | 100797 | 邮编 | CPF/CNPJ | 是 |
DPD (HR) | 100807 | 邮编 | 1000 AA | 否 |
DPD (EE) | 100808 | 邮编 | 1000 AA | 否 |
DPD (LV) | 100809 | 邮编 | 1000 AA | 否 |
DPD (LT) | 100810 | 邮编 | 1000 AA | 否 |
DPD (NL) | 100811 | 邮编 | 1000 AA | 否 |
DPD (SK) | 100812 | 邮编 | 1000 AA | 否 |
DPD (SI) | 100813 | 邮编 | 1000 AA | 否 |
DPD (CH) | 100815 | 邮编 | 1000 AA | 否 |
DHL Supply Chain APAC | 100842 | 目的地国家 | ID | 是 |
The United Pallet Network | 100862 | 邮编 | LS27 0BN | 是 |
Furdeco | 100881 | 邮编 | LS27 0BN | 是 |
Palletways | 100900 | 邮编 | 1000 AA | 否 |
Instabox | 100932 | 邮编 | 51900 | 是 |
France Express | 100936 | 邮编 | 1000 AA | 否 |
Transaher | 100959 | 邮编 | 12345 | 否 |
BJS Home Delivery | 101003 | 手机 | 8888888888 | 是 |
Palletforce | 101010 | 邮编 | S27 1BZ | 是 |
FleetOptics | 101035 | 邮编 | 1000 | 是 |
Hofmann | 101038 | 邮编 | 10000 | 是 |
Emons | 101039 | 邮编 | 10000 | 是 |
Sislógica | 101040 | 邮编 | 1000000 | 是 |
APC Overnight | 101065 | 邮编 | 1000 AA | 是 |
Arrow XL | 101076 | 邮编 | 1000 AA | 否 |
优速快递 | 190415 | 手机 | 8888 | 是 |
顺丰速运(CN) | 190766 | 手机 | 8888 | 是 |
跨越速运 (中国) | 190845 | 手机 | 8888 | 是 |
国家地区代码
- 国家信息(country)统一采用 ISO 3166-1 的二字代码来表示。
物流主状态
- 共 9 主状态,表示包裹承运中的当前状态,是枚举集合;
- 可用于筛选、分组、监控最新的跟踪情况;
- 枚举值对应更新跟踪通知中 latest_status.status 属性,在 v1 版本中是由数字代码来对应 e 属性;
枚举值 |
描述 |
---|---|
NotFound | 查询不到,进行查询操作但没有得到结果,原因请参看子状态。 |
InfoReceived | 收到信息,运输商收到下单信息,等待上门取件。 |
InTransit | 运输途中,包裹正在运输途中,具体情况请参看子状态。 |
Expired | 运输过久,包裹已经运输了很长时间而仍未投递成功。 |
AvailableForPickup | 到达待取,包裹已经到达目的地的投递点,需要收件人自取。 |
OutForDelivery | 派送途中,包裹正在投递过程中。 |
DeliveryFailure | 投递失败,包裹尝试派送但未能成功交付,原因请参看子状态。原因可能是:派送时收件人不在家、投递延误重新安排派送、收件人要求延迟派送、地址不详无法派送、因偏远地区不提供派送服务等。 |
Delivered | 成功签收,包裹已妥投。 |
Exception | 可能异常,包裹可能被退回,原因请参看子状态。原因可能是:收件人地址错误或不详、收件人拒收、包裹无人认领超过保留期等。包裹可能被海关扣留,常见扣关原因是:包含敏感违禁、限制进出口的物品、未交税款等。包裹可能在运输途中遭受损坏、丢失、延误投递等特殊情况。 |
物流子状态
- 共 30 子状态,其作用与主状态类似也是枚举集合;
- 是各主状态的细分情况;
- 子状态枚举值对应更新跟踪通知中 latest_status.sub_status 属性。
主状态枚举值 | 子状态枚举值 | 子状态描述 |
---|---|---|
NotFound | NotFound_Other | 运输商没有返回信息。 |
NotFound_InvalidCode | 物流单号无效,无法进行查询。 | |
InfoReceived | InfoReceived | 收到信息,暂无细分含义与主状态一致。 |
InTransit | InTransit_PickedUp | 已揽收,运输商已从发件人处取回包裹。 |
InTransit_Other | 其它情况,暂无细分除当前已知子状态之外的情况。 | |
InTransit_Departure | 已离港,货物离开起运地(国家/地区)港口。 | |
InTransit_Arrival | 已到港,货物到达目的地(国家/地区)港口。 | |
InTransit_CustomsProcessing | 清关中,货物在海关办理进入或出口的相关流程中。 | |
InTransit_CustomsReleased | 清关完成,货物在海关完成了进入或出口的流程。 | |
InTransit_CustomsRequiringInformation | 需要资料,在清关中流程中承运人需要提供相关资料才能完成清关。 | |
Expired | Expired_Other | 运输过久,暂无细分含义与主状态一致。 |
AvailableForPickup | AvailableForPickup_Other | 到达待取,暂无细分含义与主状态一致。 |
OutForDelivery | OutForDelivery_Other | 派送途中,暂无细分含义与主状态一致。 |
DeliveryFailure | DeliveryFailure_Other | 其它情况,暂无细分除当前已知子状态之外的情况。 |
DeliveryFailure_NoBody | 找不到收件人,派送中的包裹暂时无法联系上收件人,导致投递失败。 | |
DeliveryFailure_Security | 安全原因,派送中发现的包裹安全、清关、费用问题,导致投递失败。 | |
DeliveryFailure_Rejected | 拒收,收件人因某些原因拒绝接收包裹,导致投递失败。 | |
DeliveryFailure_InvalidAddress | 地址错误,由于收件人地址不正确,导致投递失败。 | |
Delivered | Delivered_Other | 成功签收,暂无细分含义与主状态一致。 |
Exception | Exception_Other | 其它情况,暂无细分除当前已知子状态之外的情况。 |
Exception_Returning | 退件中,包裹正在送回寄件人的途中。 | |
Exception_Returned | 退件签收,寄件人已成功收到退件。 | |
Exception_NoBody | 找不到收件人,在派送之前发现的收件人信息异常。 | |
Exception_Security | 安全原因,在派送之前发现异常,包含安全、清关、费用问题。 | |
Exception_Damage | 损坏,在承运过程中发现货物损坏了。 | |
Exception_Rejected | 拒收,在派送之前接收到有收件人拒收情况。 | |
Exception_Delayed | 延误,因各种情况导致的可能超出原定的运输周期。 | |
Exception_Lost | 丢失,因各种情况导致的货物丢失。 | |
Exception_Destroyed | 销毁,因各种情况无法完成交付的货物并进行销毁。 | |
Exception_Cancel | 取消,因为各种情况物流订单被取消了。 |
翻译语言代码
用于翻译物流事件的代码,使用方式请参考注册接口和修改信息接口说明;
语言 |
代码 |
---|---|
英文 | en |
日文 | ja |
法文 | fr |
丹麦文 | da |
泰文 | th |
德文 | de |
西班牙文 | es |
简体中文 | zh-hans |
如何获取揽收时间
- 遍历 tracking.providers[].events[]
- 优先判断,如果 sub_status == "InTransit_PickedUp",则 time_raw 内容为揽收时间。
- 如果无匹配值,则使用 sub_status == "InTransit_xxx" 的第 1 条事件时间 time_raw 做为揽收时间。
- 如果上述两种情况都没有取到 time_raw,则说明因运输商事件描述不完整无法提供。
如何获取签收时间
- 遍历 tracking.providers[].events[] 如果 sub_status == "Delivered_Other",则 time_raw 内容为签收时间。
接口参考
请求说明
示例
curl -X POST \
--header '17token:密钥' \
--header 'Content-Type:application/json' \
--data '[{"number":"RR123456789CN", "carrier":3011}]' \
https://api.17track.net/track/v2.2/接口名称
- 所有接口统一采用 http POST 方式提交请求;
- 请求和响应均使用 UTF-8 编码的 JSON 格式;
- 主要入参:
- 物流单号:物流单号必须是连续的 5 到 50 个字母、数字和中杠的组合;
- 运输商代码:必须是有效的 Key,具体可参考 运输商代码;
- 其它入参参考各接口描述;
- 请求地址:https://api.17track.net/track/v2.2
- 请求头(必填)
- 17token,内容为 密钥;
- Content-Type,内容为 application/json;
- 请求体(必填)
- 序列化的JSON内容,已知在 Google Apps Script 平台 中使用要指定请求体为 payload;
响应说明
示例1,通常在入参未按约定传入时显示。
{ "code": 0, "data": { "errors": [ { "code": -18010013, "message": "Submitted data is invalid." } ] } }
响应结果采用统一的数据封装格式:
名称 | 类型 |
描述 |
---|---|---|
code | 数值 | 错误代码 |
data | 对象 | 响应的数据内容对象封装。 |
-errors | 数组 | |
--code | 数值 | 错误代码 |
--message | 字符串 | 错误代码描述。 |
示例2,正常业务处理时显示
{
"code": 0,
"data": {
"accepted": [],
"rejected": []
}
}
响应结果采用统一的数据封装格式:
名称 | 类型 |
描述 |
---|---|---|
code | 数值 | 错误代码 |
data | 对象 | 响应的数据内容对象封装。 |
-accepted | 数组 | 对于请求中正常处理部分响应结果。 |
-rejected | 数组 | 对于请求中处理异常部分响应结果。 |
响应状态码
标准的 HTTP 状态码,描述请求的情况。
名称 | 描述 |
---|---|
200 | 请求得到正常处理,具体的处理结果需要检查返回数据。 |
401 | 请求未经授权、密钥错误、访问 IP 不在白名单内或者账号被禁用。 |
404 | 请求的 URL 地址错误。 |
429 | 访问频率超出限制。 |
500 | 服务器错误。 |
503 | 服务临时不可用。 |
错误代码
- 接口返回不成功时对应的标识,通过在响应报文的 rejected 节点中;
- {},是错误描述中动态填充内容的占位符;
名称 | 描述 |
---|---|
0 | 成功 |
-18010001 | IP 地址不在白名单内。 |
-18010002 | 访问密钥无效。 |
-18010003 | 内部服务错误,请稍候重试。 |
-18010004 | 账号被禁用。 |
-18010005 | 未授权的访问。 |
-18010010 | 需要提供数据项 {0}。 |
-18010011 | 数据项 {0} 的值无效。 |
-18010012 | 数据项 {0} 的格式无效。 |
-18010013 | 提交数据无效。 |
-18010014 | 提交物流单号参数超过 40 个最大限制。 |
-18010015 | 字段 {1} 的值 {0} 无效。 |
-18010016 | 只有邮政物流才可以设置尾程渠道。 |
-18010018 | 需要传递附加参数国家二字码和邮编,示例:'FR-12345'。 |
-18010019 | 需要传递附加参数邮编,示例:'3078CM'。 |
-18010020 | 需要传递附加参数电话,示例:'8888'。 |
-18010022 | 需要传递附加参数发货日期. 示例: '2024-01-01'. |
-18010201 | WebHook地址不能为空。 |
-18010202 | WebHook地址格式不正确。 |
-18010203 | WebHook测试失败,Http状态码:{0}。 |
-18010204 | 没有设置Webhook地址,无法推送。 |
-18010205 | IP地址格式不正确。 |
-18010206 | 推送失败。 |
-18019901 | 物流单号 {0} 已经注册过,不需重复注册。 |
-18019902 | 物流单号 {0} 还未注册,请先进行注册。 |
-18019903 | 运输商不能被识别,请访问 https://res.17track.net/asset/carrier/info/apicarrier.all.json 获取运输商代码并填写 carrier 入参再操作。 |
-18019904 | 只能重新跟踪已经停止跟踪的物流单号。 |
-18019905 | 每个物流单号只能被重新跟踪一次。 |
-18019906 | 只能停止跟踪正在跟踪中的物流单号。 |
-18019907 | 超出了每天限额。 |
-18019908 | 单量已经用完。 |
-18019909 | 暂时没有跟踪信息。 |
-18019910 | 运输商代码 {0} 不正确。 |
-18019911 | 运输商暂时不支持注册。 |
-18019801 | 存在相同单号的多个运输商注册信息, 请明确指定需要变更的现有 运输商代码 carrier_old。 |
-18019802 | 提交变更的新 运输商代码 carrier_new {0} 可能错误。 |
-18019803 | 请求变更的 运输商代码 不能相同。 |
-18019804 | 请求变更的新 运输商代码 carrier_new or final_carrier_new 必须明确指定其一。 |
-18019805 | 没有注册指定 运输商代码 {0} 的物流单号 {1},或者现有 运输商代码 carrier_old 错误。 |
-18019806 | 已停止跟踪的物流单号不能 修改运输商,请激活后再进行修改。 |
-18019807 | 超出运输商修改次数上限。 |
-18019808 | 最近注册或修改后还未返回跟踪结果,请等待跟踪结果返回后再进行修改。 |
-18019809 | 已经存在物流单号的运输商为 {0} 的注册信息,不能修改为重复的注册信息。 |
-18019810 | 满足修改条件的数据不唯一。 |
-18019811 | 没有有效的数据修改项。 |
-18019818 | 暂不支持当前运输商使用实时接口。 |
-18019817 | 系统异常,本次扣费失败。 |
-18019816 | 运输商接口异常,没有得到查询结果。 |
-18019815 | 运输商接口响应超时。 |
-18019912 | 未授权使用实时接口. |
注册物流单号
- POST https://api.17track.net/track/v2.2/register
- 该接口每次可提交 40 个物流单号;
- 提交后的物流单号会进入队列处理,正常情况约几秒内您设置的 WebHook 接口会收到推送通知。(因网络、运输商服务等问题,可能有 5 分钟以上的延迟);
- 每小时可注册 40多万 个物流单号;
- 传入翻译语言代码,在物流事件变更后且不为空时进行翻译;
请求示例
curl -X POST \
--header '17token:密钥' \
--header 'Content-Type:application/json' \
--data '[
{
"number": "RR123456789CN",
"lang": "",
"email":"",
"param": "",
"order_no": "202340984938",
"order_time": "2023/1/1",
"carrier": 3011,
"final_carrier": 21051,
"auto_detection": true,
"tag": "MyOrderId",
"remark": "My Remarks"
},
{
"number": "1234",
"tag": "My-Order-ID"
}
]' \
https://api.17track.net/track/v2.2/register
<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.17track.net/track/v2.2/register",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS =>"[\r
{
"number": "RR123456789CN",
"lang": "",
"email": "",
"param": "",
"order_no": "202340984938",
"order_time": "2023/1/1",
"carrier": 3011,
"final_carrier": 21051,
"auto_detection": true,
"tag": "MyOrderId",
"remark": "My Remarks"
},
{
"number": "1234",
"tag": "My-Order-ID"
}
]",
CURLOPT_HTTPHEADER => [
"17token: 密钥",
"content-type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}
var client = new HttpClient();
var request = new HttpRequestMessage
{
Method = HttpMethod.Post,
RequestUri = new Uri("https://api.17track.net/track/v2.2/register"),
Headers =
{
{ "17token", "密钥" },
},
Content = new StringContent("[
{
"number": "RR123456789CN",
"lang": "",
"email": "",
"param": "",
"order_no": "202340984938",
"order_time": "2023/1/1",
"carrier": 3011,
"final_carrier": 21051,
"auto_detection": true,
"tag": "MyOrderId",
"remark": "My Remarks"
},
{
"number": "1234",
"tag": "My-Order-ID"
}
]")
{
Headers =
{
ContentType = new MediaTypeHeaderValue("application/json")
}
}
};
using (var response = await client.SendAsync(request))
{
response.EnsureSuccessStatusCode();
var body = await response.Content.ReadAsStringAsync();
Console.WriteLine(body);
}
OkHttpClient client = new OkHttpClient();
MediaType mediaType = MediaType.parse("application/json");
String value = "[
{
"number": "RR123456789CN",
"lang": "",
"email": "",
"param": "",
"order_no": "202340984938",
"order_time": "2023/1/1",
"carrier": 3011,
"final_carrier": 21051,
"auto_detection": true,
"tag": "MyOrderId",
"remark": "My Remarks"
},
{
"number": "1234",
"tag": "My-Order-ID"
}
]";
RequestBody body = RequestBody.create(mediaType, value);
Request request = new Request.Builder()
.url("https://api.17track.net/track/v2.2/register")
.post(body)
.addHeader("content-type", "application/json")
.addHeader("17token", "密钥")
.build();
Response response = client.newCall(request).execute();
response.body();
const axios = require("axios");
const options = {
method: 'POST',
url: 'https://api.17track.net/track/v2.2/register',
headers: {
'content-type': 'application/json',
'17token': '密钥',
},
data: '[
{
"number":"RR123456789CN",
"lang":"",
"email":"",
"param":"",
"order_no":"202340984938",
"order_time":"2023/1/1",
"carrier":3011,
"final_carrier":21051,
"auto_detection":true,
"tag":"MyOrderId",
"remark":"My-Remarks"
},
{
"number":"1234",
"tag":"My-Order-ID"
}
]'
};
axios.request(options).then(function (response) {
console.log(response.data);
}).catch(function (error) {
console.error(error);
});
import requests
url = "https://api.17track.net/track/v2.2/register"
payload = [
{
"number": "RR123456789CN",
"lang": "",
"email": "",
"param": "",
"order_no": "202340984938",
"order_time": "2023/1/1",
"carrier": 3011,
"final_carrier": 21051,
"auto_detection": True,
"tag": "MyOrderId",
"remark":"My Remarks"
},
{
"number": "1234",
"tag": "My-Order-ID"
}
]
headers = {
"content-type": "application/json",
"17token": "密钥"
}
response = requests.request("POST", url, json=payload, headers=headers)
print(response.text)
请求参数说明:
参数名称 | 是否必须 |
类型 |
描述 |
---|---|---|---|
number | 是 | 字符串 | 物流单号需满足 单号格式要求。 |
lang | 否 | 字符串 | 用于翻译物流事件,详细如下: 1. 指定语言代码; 2. 翻译需要额外消耗 1 个单量,即:跟踪 + 翻译实际扣 2 单; 3. 成功注册单号后在首次跟踪到结果时进行翻译并扣费,后续更新会自动翻译并不再扣费; |
否 | 字符串 | 用户邮箱,最长 250 个字符。如邮箱有效且开启通知功能,当物流状态发生变化时,将通过邮箱告知用户。 | |
param | 否 | 字符串 | 物流单号附加跟踪参数(较少的运输商要求提供邮编或下单日期才能查询包裹信息); |
order_no | 否 | 字符串 | 订单编号,3 到 50 个字符。 |
order_time | 否 | 字符串 | 订单日期,买家购买商品的下单时间,可用于计算上网率时效,例如:2023/1/1 。 |
carrier | 否 | 数值 | 运输商代码: 1. 系统可以识别大多数万国邮联(UPU)或合作运输商的定制物流单号(无需指定运输商代码),如果传错系统会进行纠正并返回正确的 运输商代码; 2. 指定运输商进行注册成功后返回的 物流主状态是查询不到,则可能是数据未上网、运输商服务异常、指定错运输商等情况; 3. 返回错误代码 -18019903 表示系统无法识别物流单号所属运输商; 4. 因注册成功后会扣减单量,建议您明确物流单号所对应的 运输商 再进行操作; 5. 因指定错的运输商注册成功的物流单号,可以使用 修改运输商接口调整; |
final_carrier | 否 | 数值 | 尾程运输商代码(仅支持邮政渠道)。 |
auto_detection | 否 | 布尔值 | 是否开启运输商自动检测,默认为 true,但是不确保一定可以识别到且不保证识别结果的准确性,如果用户有传入有效的 carrier 参数,则该参数无效。 |
tag | 否 | 字符串 | 自定义标签,最长 100 个字符,可填入备注描述、数据标识。 |
remark | 否 | 字符串 | 自定义备注,最长 1000 个字符,可用于描述当前包裹的情况。 |
响应示例
{
"code": 0,
"data": {
"accepted": [
{
"origin": 1,
"number": "RR123456789CN",
"carrier": 3011,
"email": null,
"tag": "MyOrderID",
"lang": null,
}
],
"rejected": [
{
"number": "1234",
"tag": "My-Order-Id",
"error": {
"code": -18010012,
"message": "The format of '1234' is invalid."
}
}
]
}
}
响应结果说明:
名称 |
类型 |
描述 |
---|---|---|
code | 数值 | 错误代码。 |
data | 对象 | 请求对应的响应数据。 |
-accepted | 数组 | 正常接受注册的物流单号,同时返回对应的运输商代码,如果执行过纠正策略,返回的运输商可能和传入的不同。 |
--number | 字符串 | 正常接受注册的物流单号。 |
--tag | 字符串 | 自定义标识,参考 【注册物流单号】 入参说明。 |
--carrier | 数值 | 正常接受注册的 运输商代码。 |
字符串 | 邮箱 | |
--lang | 字符串 | 翻译语言 |
--origin | 数值 | 正常接受注册的运输商识别方式,以枚举标识返回,内容是: 1 : 准确识别(包含强制矫正过的); 2 : 用户输入; 3 : 自动检测(不确保准确); |
-rejected | 数组 | 拒绝接受请求的单号信息集合。 |
--number | 字符串 | 物流单号。 |
--error | 对象 | 错误信息集合。 |
--code | 数值 | 错误提示代码,具体错误原因可以检查对应的 错误代码 |
--message | 字符串 | 错误代码描述。 |
修改运输商
- POST https://api.17track.net/track/v2.2/changecarrier
- 该接口每次可提交 40 个物流单号;
- 用于修改还在自动跟踪的物流单号的运输商;
- 每个单号可以修改 5 次;
请求示例
curl -X POST \
--header '17token:密钥' \
--header 'Content-Type:application/json' \
--data '[
{
"number": "RR123456789CN",
"carrier_old": 3013,
"carrier_new": 3011
},
{
"number": "21213123123230",
"carrier_old": 3011,
"carrier_new": 21051,
}
]' \
https://api.17track.net/track/v2.2/changecarrier
<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.17track.net/track/v2.2/changecarrier",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => "[
{
"number": "RR123456789CN",
"carrier_old": 3013,
"carrier_new": 3011
},
{
"number": "21213123123230",
"carrier_old": 3011,
"carrier_new": 21051,
}
]",
CURLOPT_HTTPHEADER => [
"17token: 密钥",
"content-type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}
var client = new HttpClient();
var request = new HttpRequestMessage
{
Method = HttpMethod.Post,
RequestUri = new Uri("https://api.17track.net/track/v2.2/changecarrier"),
Headers =
{
{ "17token", "密钥" },
},
Content = new StringContent("[
{
"number": "RR123456789CN",
"carrier_old": 3013,
"carrier_new": 3011
},
{
"number": "21213123123230",
"carrier_old": 3011,
"carrier_new": 21051,
}
]")
{
Headers =
{
ContentType = new MediaTypeHeaderValue("application/json")
}
}
};
using (var response = await client.SendAsync(request))
{
response.EnsureSuccessStatusCode();
var body = await response.Content.ReadAsStringAsync();
Console.WriteLine(body);
}
OkHttpClient client = new OkHttpClient();
MediaType mediaType = MediaType.parse("application/json");
String value = "[
{
"number": "RR123456789CN",
"carrier_old": 3013,
"carrier_new": 3011
},
{
"number": "21213123123230",
"carrier_old": 3011,
"carrier_new": 21051,
}
]";
RequestBody body = RequestBody.create(mediaType, value);
Request request = new Request.Builder()
.url("https://api.17track.net/track/v2.2/changecarrier")
.post(body)
.addHeader("content-type", "application/json")
.addHeader("17token", "密钥")
.build();
Response response = client.newCall(request).execute();
response.body();
const axios = require("axios");
const options = {
method: 'POST',
url: 'https://api.17track.net/track/v2.2/changecarrier',
headers: {
'content-type': 'application/json',
'17token': '密钥'
},
data: '[
{
"number": "RR123456789CN",
"carrier_old": 3013,
"carrier_new": 3011
},
{
"number": "21213123123230",
"carrier_old": 3011,
"carrier_new": 21051,
}
]'
};
axios.request(options).then(function (response) {
console.log(response.data);
}).catch(function (error) {
console.error(error);
});
import requests
url = "https://api.17track.net/track/v2.2/changecarrier"
payload = [
{
"number": "RR123456789CN",
"carrier_old": 3013,
"carrier_new": 3011
},
{
"number": "21213123123230",
"carrier_old": 3011,
"carrier_new": 21051,
}
]
headers = {
"content-type": "application/json",
"17token": "密钥"
}
response = requests.request("POST", url, json=payload, headers=headers)
print(response.text)
请求参数说明:
名称 | 是否必须 |
类型 |
描述 |
---|---|---|---|
number | 是 | 字符串 | 物流单号需满足 单号格式要求。 |
carrier_old | 否 | 数值 | 旧的 运输商代码,如果没有注册相同单号的多个运输商的情况下可以不设置。 |
carrier_new | 是 | 数值 | 新的 运输商代码。 |
final_carrier_old | 否 | 数值 | (仅邮政物流渠道支持)旧的尾程 运输商代码,如果该注册单号没有重复,可以不设置(仅邮政单号支持)。 |
final_carrier_new | 是 | 数值 | (仅邮政物流渠道支持)新的尾程 运输商代码。 |
响应示例
{
"code": 0,
"data": {
"accepted": [
{
"number": "RR123456789CN",
"carrier": 3011
}
],
"rejected": [
{
"number": "21213123123230",
"error": {
"code": -18019809,
"message": "The registration information of the carrier with tracking number 'Usa' already exists and cannot be changed to a duplicate registration information."
}
}
]
}
}
响应结果说明:
名称 | 类型 |
描述 |
---|---|---|
code | 数值 | 错误代码。 |
data | 对象 | 请求对应的响应数据。 |
-accepted | 数组 | 正常接受且成功执行变更的单号,同时返回对应的最新的 运输商代码。 |
--number | 字符串 | 物流单号。 |
--carrier | 数值 | 运输商代码。 |
-rejected | 数组 | 拒绝接受请求的单号信息集合。 |
--number | 字符串 | 物流单号。 |
--error | 对象 | 错误信息集合。 |
--code | 数值 | 错误提示代码,具体错误原因可以检查对应的 错误代码 |
--message | 字符串 | 错误代码描述。 |
修改信息
- POST https://api.17track.net/track/v2.2/changeinfo
- 该接口每次可提交 40 个物流单号;
- 用于修改和跟踪相关的附属信息;
请求示例
curl -X POST \
--header '17token:密钥' \
--header 'Content-Type:application/json' \
--data '[
{
"number": "RR123456789CN",
"carrier": 3011,
"items": {
"lang": "en",
"param": "8888",
"tag": "This is my order id."
}
},
{
"number": "21213123123230",
"carrier": 11031,
"items": {
"tag":"This is my order id."
}
}
]'
https://api.17track.net/track/v2.2/changeinfo
<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.17track.net/track/v2.2/changeinfo",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => "[
{
"number": "RR123456789CN",
"carrier": 3011,
"items": {
"lang": "en",
"param": "8888",
"tag": "This is my order id."
}
},
{
"number": "21213123123230",
"carrier": 11031,
"items": {
"tag":"This is my order id."
}
}
]",
CURLOPT_HTTPHEADER => [
"17token: 密钥",
"content-type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}
var client = new HttpClient();
var request = new HttpRequestMessage
{
Method = HttpMethod.Post,
RequestUri = new Uri("https://api.17track.net/track/v2.2/changeinfo"),
Headers =
{
{ "17token", "密钥" },
},
Content = new StringContent("[
{
"number": "RR123456789CN",
"carrier": 3011,
"items": {
"lang": "en",
"param": "8888",
"tag": "This is my order id."
}
},
{
"number": "21213123123230",
"carrier": 11031,
"items": {
"tag":"This is my order id."
}
}
]")
{
Headers =
{
ContentType = new MediaTypeHeaderValue("application/json")
}
}
};
using (var response = await client.SendAsync(request))
{
response.EnsureSuccessStatusCode();
var body = await response.Content.ReadAsStringAsync();
Console.WriteLine(body);
}
OkHttpClient client = new OkHttpClient();
MediaType mediaType = MediaType.parse("application/json");
String value = "[
{
"number": "RR123456789CN",
"carrier": 3011,
"items": {
"lang": "en",
"param": "8888",
"tag": "This is my order id."
}
},
{
"number": "21213123123230",
"carrier": 11031,
"items": {
"tag":"This is my order id."
}
}
]";
RequestBody body = RequestBody.create(mediaType, value);
Request request = new Request.Builder()
.url("https://api.17track.net/track/v2.2/changeinfo")
.post(body)
.addHeader("content-type", "application/json")
.addHeader("17token", "密钥")
.build();
Response response = client.newCall(request).execute();
response.body();
const axios = require("axios");
const options = {
method: 'POST',
url: 'https://api.17track.net/track/v2.2/changeinfo',
headers: {
'content-type': 'application/json',
'17token': '密钥'
},
data: '[
{
"number": "RR123456789CN",
"carrier": 3011,
"items": {
"lang": "en",
"param": "8888",
"tag": "This is my order id."
}
},
{
"number": "21213123123230",
"carrier": 11031,
"items": {
"tag":"This is my order id."
}
}
]'
};
axios.request(options).then(function (response) {
console.log(response.data);
}).catch(function (error) {
console.error(error);
});
import requests
url = "https://api.17track.net/track/v2.2/changeinfo"
payload = [
{
"number": "RR123456789CN",
"carrier": 3011,
"items": {
"lang": "en",
"param": "8888",
"tag": "This is my order id."
}
},
{
"number": "21213123123230",
"carrier": 11031,
"items": {
"tag":"This is my order id."
}
}
]
headers = {
"content-type": "application/json",
"17token": "密钥"
}
response = requests.request("POST", url, json=payload, headers=headers)
print(response.text)
请求参数说明:
名称 | 是否必须 |
类型 |
描述 |
---|---|---|---|
number | 是 | 字符串 | 物流单号需满足 单号格式要求。 |
carrier | 否 | 数值 | 运输商代码。 |
items | 是 | 对象 | 需要修改的数据项目集合。 |
--tag | 否 | 字符串 | 自定义标签,最长 100 个字符,可填入备注描述、数据标识。 |
--param | 否 | 字符串 | 附加跟踪参数。 |
--lang | 否 | 字符串 | 指定翻译语言代码在下次物流事件变更时自动翻译。 |
--remark | 否 | 字符串 | 备注,最长 1000 个字符,可用于描述当前包裹的情况。 |
--order_no | 否 | 字符串 | 订单编号,3 到 50 个字符。 |
--order_time | 否 | 字符串 | 订单日期,买家购买商品的下单时间,可用于计算上网率时效,例如:2023/1/1。 |
响应示例
{
"code": 0,
"data": {
"accepted": [
{
"number": "RR123456789CN",
"carrier": 3011
}
],
"rejected": [
{
"number": "21213123123230",
"error": {
"code": -18019902,
"message": "The tracking number '21213123123230' does not register, please register first."
}
}
]
}
}
响应结果说明:
名称 | 类型 |
描述 |
---|---|---|
code | 数值 | 错误代码。 |
data | 对象 | 请求对应的响应数据。 |
-accepted | 数组 | 正常接受且成功执行变更的单号,同时返回对应的最新的 运输商代码。 |
--number | 字符串 | 物流单号。 |
--carrier | 数值 | 运输商代码。 |
-rejected | 数组 | 拒绝接受请求的单号信息集合。 |
--number | 字符串 | 物流单号。 |
--error | 对象 | 错误信息集合。 |
--code | 数值 | 错误提示代码,具体错误原因可以检查对应的 错误代码 |
--message | 字符串 | 错误代码描述。 |
停止跟踪
- POST https://api.17track.net/track/v2.2/stoptrack
- 该接口每次可提交 40 个物流单号;
- 把自动跟踪的物流单号停掉,与 重启跟踪 接口为互斥操作;
请求示例
curl -X POST \
--header '17token:密钥' \
--header 'Content-Type:application/json' \
--data '[
{
"number": "RR123456789CN",
"carrier": 3011
},
{
"number": "21213123123230",
"carrier": 21051
}
]'\
https://api.17track.net/track/v2.2/stoptrack
<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.17track.net/track/v2.2/stoptrack",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => "[
{
"number": "RR123456789CN",
"carrier": 3011
},
{
"number": "21213123123230",
"carrier": 21051
}
]",
CURLOPT_HTTPHEADER => [
"17token: 密钥",
"content-type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}
var client = new HttpClient();
var request = new HttpRequestMessage
{
Method = HttpMethod.Post,
RequestUri = new Uri("https://api.17track.net/track/v2.2/stoptrack"),
Headers =
{
{ "17token", "密钥" },
},
Content = new StringContent("[
{
"number": "RR123456789CN",
"carrier": 3011
},
{
"number": "21213123123230",
"carrier": 21051
}
]")
{
Headers =
{
ContentType = new MediaTypeHeaderValue("application/json")
}
}
};
using (var response = await client.SendAsync(request))
{
response.EnsureSuccessStatusCode();
var body = await response.Content.ReadAsStringAsync();
Console.WriteLine(body);
}
OkHttpClient client = new OkHttpClient();
MediaType mediaType = MediaType.parse("application/json");
String value = "[
{
"number": "RR123456789CN",
"carrier": 3011
},
{
"number": "21213123123230",
"carrier": 21051
}
]";
RequestBody body = RequestBody.create(mediaType, value);
Request request = new Request.Builder()
.url("https://api.17track.net/track/v2.2/stoptrack")
.post(body)
.addHeader("content-type", "application/json")
.addHeader("17token", "密钥")
.build();
Response response = client.newCall(request).execute();
response.body();
const axios = require("axios");
const options = {
method: 'POST',
url: 'https://api.17track.net/track/v2.2/stoptrack',
headers: {
'content-type': 'application/json',
'17token': '密钥'
},
data: '[
{
"number": "RR123456789CN",
"carrier": 3011
},
{
"number": "21213123123230",
"carrier": 21051
}
]'
};
axios.request(options).then(function (response) {
console.log(response.data);
}).catch(function (error) {
console.error(error);
});
import requests
url = "https://api.17track.net/track/v2.2/stoptrack"
payload = [
{
"number": "RR123456789CN",
"carrier": 3011
},
{
"number": "21213123123230",
"carrier": 21051
}
]
headers = {
"content-type": "application/json",
"17token": "密钥"
}
response = requests.request("POST", url, json=payload, headers=headers)
print(response.text)
请求参数说明:
名称 | 是否必须 |
类型 |
描述 |
---|---|---|---|
number | 是 | 字符串 | 物流单号需满足 单号格式要求。 |
carrier | 否 | 数值 | 运输商代码,不传的时候如果有多条相同单号的数据(运输商不同),则处理多条。 |
示例
{
"code": 0,
"data": {
"accepted": [
{
"number": "RR123456789CN",
"carrier": 3011
}
],
"rejected": [
{
"number": "21213123123230",
"error": {
"code": -18019902,
"message": "The tracking number '21213123123230' does not register, please register first."
}
}
]
}
}
响应结果说明:
名称 | 类型 |
描述 |
---|---|---|
code | 数值 | 错误代码。 |
data | 对象 | 请求对应的响应数据。 |
-accepted | 数组 | 正常接受并处理的请求。 |
--number | 字符串 | 物流单号。 |
--carrier | 数值 | 运输商代码。 |
-rejected | 数组 | 拒绝接受请求的单号信息集合。 |
--number | 字符串 | 物流单号。 |
--error | 对象 | 错误信息集合。 |
--code | 数值 | 错误提示代码,具体错误原因可以检查对应的 错误代码 |
--message | 字符串 | 错误代码描述。 |
重启跟踪
- POST https://api.17track.net/track/v2.2/retrack
- 该接口每次可提交 40 个物流单号;
- 把停止跟踪状态的物流单号重新启动为自动跟踪状态;
- 与 停止跟踪 接口为互斥操作;
- 每个物流单只能重启跟踪 1 次;
请求示例
curl -X POST \
--header '17token:密钥' \
--header 'Content-Type:application/json' \
--data '[
{
"number": "RR123456789CN",
"carrier": 3011
},
{
"number": "21213123123230",
"carrier": 21051
}
]' \
https://api.17track.net/track/v2.2/retrack
<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.17track.net/track/v2.2/retrack",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => "[
{
"number": "RR123456789CN",
"carrier": 3011
},
{
"number": "21213123123230",
"carrier": 21051
}
]",
CURLOPT_HTTPHEADER => [
"17token: 密钥",
"content-type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}
var client = new HttpClient();
var request = new HttpRequestMessage
{
Method = HttpMethod.Post,
RequestUri = new Uri("https://api.17track.net/track/v2.2/retrack"),
Headers =
{
{ "17token", "密钥" },
},
Content = new StringContent("[
{
"number": "RR123456789CN",
"carrier": 3011
},
{
"number": "21213123123230",
"carrier": 21051
}
]")
{
Headers =
{
ContentType = new MediaTypeHeaderValue("application/json")
}
}
};
using (var response = await client.SendAsync(request))
{
response.EnsureSuccessStatusCode();
var body = await response.Content.ReadAsStringAsync();
Console.WriteLine(body);
}
OkHttpClient client = new OkHttpClient();
MediaType mediaType = MediaType.parse("application/json");
String value = "[
{
"number": "RR123456789CN",
"carrier": 3011
},
{
"number": "21213123123230",
"carrier": 21051
}
]";
RequestBody body = RequestBody.create(mediaType, value);
Request request = new Request.Builder()
.url("https://api.17track.net/track/v2.2/retrack")
.post(body)
.addHeader("content-type", "application/json")
.addHeader("17token", "密钥")
.build();
Response response = client.newCall(request).execute();
response.body();
const axios = require("axios");
const options = {
method: 'POST',
url: 'https://api.17track.net/track/v2.2/retrack',
headers: {
'content-type': 'application/json',
'17token': '密钥'
},
data: '[
{
"number": "RR123456789CN",
"carrier": 3011
},
{
"number": "21213123123230",
"carrier": 21051
}
]'
};
axios.request(options).then(function (response) {
console.log(response.data);
}).catch(function (error) {
console.error(error);
});
import requests
url = "https://api.17track.net/track/v2.2/retrack"
payload = [
{
"number": "RR123456789CN",
"carrier": 3011
},
{
"number": "21213123123230",
"carrier": 21051
}
]
headers = {
"content-type": "application/json",
"17token": "密钥"
}
response = requests.request("POST", url, json=payload, headers=headers)
print(response.text)
请求参数说明:
名称 | 是否必须 |
类型 |
描述 |
---|---|---|---|
number | 是 | 字符串 | 物流单号需满足 单号格式要求。 |
carrier | 否 | 数值 | 运输商代码,不传的时候如果有多条相同单号的数据(运输商不同),则处理多条。 |
响应示例
{
"code": 0,
"data": {
"accepted": [
{
"number": "RR123456789CN",
"carrier": 3011
}
],
"rejected": [
{
"number": "21213123123230",
"error": {
"code": -18019904,
"message": "Retrack is not allowed. You can only retrack stopped number."
}
}
]
}
}
响应结果说明:
名称 | 类型 |
描述 |
---|---|---|
code | 数值 | 错误代码。 |
data | 对象 | 请求对应的响应数据。 |
-accepted | 数组 | 正常接受并处理的请求。 |
--number | 字符串 | 物流单号。 |
--carrier | 数值 | 运输商代码。 |
-rejected | 数组 | 拒绝接受请求的单号信息集合。 |
--number | 字符串 | 物流单号。 |
--error | 对象 | 错误信息集合。 |
--code | 数值 | 错误提示代码,具体错误原因可以检查对应的 错误代码 |
--message | 字符串 | 错误代码描述。 |
删除物流单号
- POST https://api.17track.net/track/v2.2/deletetrack
- 该接口每次可提交 40 个物流单号;
- 删除后无法恢复;
请求示例
curl -X POST \
--header '17token:密钥' \
--header 'Content-Type:application/json' \
--data '[
{
"number": "RR123456789CN",
"carrier": 3011
},
{
"number": "21213123123230",
"carrier": 21051
}
]' \
https://api.17track.net/track/v2.2/deletetrack
<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.17track.net/track/v2.2/deletetrack",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => "[
{
"number": "RR123456789CN",
"carrier": 3011
},
{
"number": "21213123123230",
"carrier": 21051
}
]",
CURLOPT_HTTPHEADER => [
"17token: 密钥",
"content-type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}
var client = new HttpClient();
var request = new HttpRequestMessage
{
Method = HttpMethod.Post,
RequestUri = new Uri("https://api.17track.net/track/v2.2/deletetrack"),
Headers =
{
{ "17token", "密钥" },
},
Content = new StringContent("[
{
"number": "RR123456789CN",
"carrier": 3011
},
{
"number": "21213123123230",
"carrier": 21051
}
]")
{
Headers =
{
ContentType = new MediaTypeHeaderValue("application/json")
}
}
};
using (var response = await client.SendAsync(request))
{
response.EnsureSuccessStatusCode();
var body = await response.Content.ReadAsStringAsync();
Console.WriteLine(body);
}
OkHttpClient client = new OkHttpClient();
MediaType mediaType = MediaType.parse("application/json");
String value = "[
{
"number": "RR123456789CN",
"carrier": 3011
},
{
"number": "21213123123230",
"carrier": 21051
}
]";
RequestBody body = RequestBody.create(mediaType, value);
Request request = new Request.Builder()
.url("https://api.17track.net/track/v2.2/deletetrack")
.post(body)
.addHeader("content-type", "application/json")
.addHeader("17token", "密钥")
.build();
Response response = client.newCall(request).execute();
response.body();
const axios = require("axios");
const options = {
method: 'POST',
url: 'https://api.17track.net/track/v2.2/deletetrack',
headers: {
'content-type': 'application/json',
'17token': '密钥'
},
data: '[
{
"number": "RR123456789CN",
"carrier": 3011
},
{
"number": "21213123123230",
"carrier": 21051
}
]'
};
axios.request(options).then(function (response) {
console.log(response.data);
}).catch(function (error) {
console.error(error);
});
import requests
url = "https://api.17track.net/track/v2.2/deletetrack"
payload = [
{
"number": "RR123456789CN",
"carrier": 3011
},
{
"number": "21213123123230",
"carrier": 21051
}
]
headers = {
"content-type": "application/json",
"17token": "密钥"
}
response = requests.request("POST", url, json=payload, headers=headers)
print(response.text)
请求参数说明:
名称 | 是否必须 |
类型 |
描述 |
---|---|---|---|
number | 是 | 字符串 | 物流单号需满足 单号格式要求。 |
carrier | 否 | 数值 | 运输商代码,不传的时候如果有多条相同单号的数据(运输商不同),则处理多条。 |
响应示例
{
"code": 0,
"data": {
"accepted": [
{
"number": "RR123456789CN",
"carrier": 3011
}
],
"rejected": [
{
"number": "21213123123230",
"error": {
"code": -18019902,
"message": "The tracking number '21213123123230' does not register, please register first."
}
}
]
}
}
响应结果说明:
名称 | 类型 |
描述 |
---|---|---|
code | 数值 | 错误代码。 |
data | 对象 | 请求对应的响应数据。 |
-accepted | 数组 | 正常接受并处理的请求。 |
--number | 字符串 | 物流单号。 |
--carrier | 数值 | 运输商代码。 |
-rejected | 数组 | 拒绝接受请求的单号信息集合。 |
--number | 字符串 | 物流单号。 |
--error | 对象 | 错误信息集合。 |
--code | 数值 | 错误提示代码,具体错误原因可以检查对应的 错误代码 |
--message | 字符串 | 错误代码描述。 |
获取当前剩余单量
- POST https://api.17track.net/track/v2.2/getquota
- 用来获取当前用户的单量信息,无参数;
请求示例
curl -X POST \
--header '17token:密钥' \
--header 'Content-Type:application/json' \
https://api.17track.net/track/v2.2/getquota
<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.17track.net/track/v2.2/getquota",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => "[]",
CURLOPT_HTTPHEADER => [
"17token: 密钥",
"content-type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}
var client = new HttpClient();
var request = new HttpRequestMessage
{
Method = HttpMethod.Post,
RequestUri = new Uri("https://api.17track.net/track/v2.2/getquota"),
Headers =
{
{ "17token", "密钥" },
},
Content = new StringContent("[]")
{
Headers =
{
ContentType = new MediaTypeHeaderValue("application/json")
}
}
};
using (var response = await client.SendAsync(request))
{
response.EnsureSuccessStatusCode();
var body = await response.Content.ReadAsStringAsync();
Console.WriteLine(body);
}
OkHttpClient client = new OkHttpClient();
MediaType mediaType = MediaType.parse("application/json");
String value = "[]";
RequestBody body = RequestBody.create(mediaType, value);
Request request = new Request.Builder()
.url("https://api.17track.net/track/v2.2/getquota")
.post(body)
.addHeader("content-type", "application/json")
.addHeader("17token", "密钥")
.build();
Response response = client.newCall(request).execute();
response.body();
const axios = require("axios");
const options = {
method: 'POST',
url: 'https://api.17track.net/track/v2.2/getquota',
headers: {
'content-type': 'application/json',
'17token': '密钥'
},
data: '[]'
};
axios.request(options).then(function (response) {
console.log(response.data);
}).catch(function (error) {
console.error(error);
});
import requests
url = "https://api.17track.net/track/v2.2/getquota"
payload = []
headers = {
"content-type": "application/json",
"17token": "密钥"
}
response = requests.request("POST", url, json=payload, headers=headers)
print(response.text)
响应示例
{
"code": 0,
"data": {
"quota_total": 1100,
"quota_used": 2,
"quota_remain": 1098,
"today_used": 0,
"max_track_daily": 10000000,
"free_email_quota": 300,
"free_email_quotaused": 0
}
}
响应结果说明:
名称 | 类型 |
描述 |
---|---|---|
code | 数值 | 错误代码。 |
data | 对象 | 请求对应的响应数据。 |
-quota_total | 数值 | 当前生效的总计可用单量。 |
-quota_used | 数值 | 当前已经使用的单量。 |
-quota_remain | 数值 | 当前剩余的可用单量。 |
-today_used | 数值 | 当天已使用单量。 |
-max_track_daily | 数值 | 当前设置的每天最大可用单量,0 表示无限制。 |
-free_email_quota | 数值 | 邮件免费额度。 |
-free_email_quotaused | 数值 | 邮件已经使用额度 |
获取列表
- POST https://api.17track.net/track/v2.2/gettracklist
- 查询注册单号列表信息,该接口每次返回 1 页,每页 40 条信息;
- 此接口不发起查询动作,是从自动跟踪的结果中返回对应运单信息;
请求示例
curl -X POST \
--header '17token:密钥' \
--header 'Content-Type:application/json' \
--data '{
"number": "RR123456789CN,RR111111111CN",
"carrier": 3011,
"data_origin": "Api",
"register_time_from": "2019-01-01",
"register_time_to": "2019-02-01",
"track_time_from": "2019-01-01",
"track_time_to": "2019-12-01",
"push_time_from": "2019-01-01",
"push_time_to": "2019-12-01",
"push_status": "Success",
"stop_track_time_from": "2019-01-01",
"stop_track_time_to": "2019-12-01",
"package_status": "NotFound",
"tracking_status": "Tracking",
"page_no": 1,
"order_by": "PushTimeAsc"
}' \
https://api.17track.net/track/v2.2/gettracklist
<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.17track.net/track/v2.2/gettracklist",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS =>'{
"number": "RR123456789CN,RR111111111CN",
"carrier": 3011,
"data_origin": "Api",
"register_time_from": "2019-01-01",
"register_time_to": "2019-02-01",
"track_time_from": "2019-01-01",
"track_time_to": "2019-12-01",
"push_time_from": "2019-01-01",
"push_time_to": "2019-12-01",
"push_status": "Success",
"stop_track_time_from": "2019-01-01",
"stop_track_time_to": "2019-12-01",
"package_status": "NotFound",
"tracking_status": "Tracking",
"page_no": 1,
"order_by": "PushTimeAsc"
}',
CURLOPT_HTTPHEADER => [
"17token: 密钥",
"content-type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}
var client = new HttpClient();
var request = new HttpRequestMessage
{
Method = HttpMethod.Post,
RequestUri = new Uri("https://api.17track.net/track/v2.2/gettracklist"),
Headers =
{
{ "17token", "密钥" },
},
Content = new StringContent("{
"number": "RR123456789CN,RR111111111CN",
"carrier": 3011,
"data_origin": "Api",
"register_time_from": "2019-01-01",
"register_time_to": "2019-02-01",
"track_time_from": "2019-01-01",
"track_time_to": "2019-12-01",
"push_time_from": "2019-01-01",
"push_time_to": "2019-12-01",
"push_status": "Success",
"stop_track_time_from": "2019-01-01",
"stop_track_time_to": "2019-12-01",
"package_status": "NotFound",
"tracking_status": "Tracking",
"page_no": 1,
"order_by": "PushTimeAsc"
}")
{
Headers =
{
ContentType = new MediaTypeHeaderValue("application/json")
}
}
};
using (var response = await client.SendAsync(request))
{
response.EnsureSuccessStatusCode();
var body = await response.Content.ReadAsStringAsync();
Console.WriteLine(body);
}
OkHttpClient client = new OkHttpClient();
MediaType mediaType = MediaType.parse("application/json");
String value = "{
"number": "RR123456789CN,RR111111111CN",
"carrier": 3011,
"data_origin": "Api",
"register_time_from": "2019-01-01",
"register_time_to": "2019-02-01",
"track_time_from": "2019-01-01",
"track_time_to": "2019-12-01",
"push_time_from": "2019-01-01",
"push_time_to": "2019-12-01",
"push_status": "Success",
"stop_track_time_from": "2019-01-01",
"stop_track_time_to": "2019-12-01",
"package_status": "NotFound",
"tracking_status": "Tracking",
"page_no": 1,
"order_by": "PushTimeAsc"
}";
RequestBody body = RequestBody.create(mediaType, value);
Request request = new Request.Builder()
.url("https://api.17track.net/track/v2.2/gettracklist")
.post(body)
.addHeader("content-type", "application/json")
.addHeader("17token", "密钥")
.build();
Response response = client.newCall(request).execute();
response.body();
const axios = require("axios");
const options = {
method: 'POST',
url: 'https://api.17track.net/track/v2.2/gettracklist',
headers: {
'content-type': 'application/json',
'17token': '密钥'
},
data: JSON.stringify({
"number": "RR123456789CN,RR111111111CN",
"carrier": 3011,
"data_origin": "Api",
"register_time_from": "2019-01-01",
"register_time_to": "2019-02-01",
"track_time_from": "2019-01-01",
"track_time_to": "2019-12-01",
"push_time_from": "2019-01-01",
"push_time_to": "2019-12-01",
"push_status": "Success",
"stop_track_time_from": "2019-01-01",
"stop_track_time_to": "2019-12-01",
"package_status": "NotFound",
"tracking_status": "Tracking",
"page_no": 1,
"order_by": "PushTimeAsc"
});
axios.request(options).then(function (response) {
console.log(response.data);
}).catch(function (error) {
console.error(error);
});
import requests
url = "https://api.17track.net/track/v2.2/gettracklist"
payload = {
"number": "RR123456789CN,RR111111111CN",
"carrier": 3011,
"data_origin": "Api",
"register_time_from": "2019-01-01",
"register_time_to": "2019-02-01",
"track_time_from": "2019-01-01",
"track_time_to": "2019-12-01",
"push_time_from": "2019-01-01",
"push_time_to": "2019-12-01",
"push_status": "Success",
"stop_track_time_from": "2019-01-01",
"stop_track_time_to": "2019-12-01",
"package_status": "NotFound",
"tracking_status": "Tracking",
"page_no": 1,
"order_by": "PushTimeAsc"
}
headers = {
"content-type": "application/json",
"17token": "密钥"
}
response = requests.request("POST", url, json=payload, headers=headers)
print(response.text)
请求参数说明:
名称 | 是否必须 |
类型 |
描述 |
---|---|---|---|
number | 否 | 字符串 | 物流单号,传入 1 个单号为模糊查找,多个为精确查找,最多可筛选 200 个单号(用逗号分割),每个单号需满足格式要求。 |
carrier | 否 | 数值 | 运输商代码。 |
data_origin | 否 | 枚举 | 单号注册的来源。 Api : 接口 Manual : 添加单号 Import : 表格导入 |
package_status | 否 | 字符串 | 包裹状态。 |
register_time_from | 否 | 日期时间 | 注册的起始时间。 |
register_time_to | 否 | 日期时间 | 注册的结束时间。 |
tracking_status | 否 | 枚举 | 跟踪状态: Tracking:正在跟踪; Stopped:停止跟踪; |
track_time_from | 否 | 日期时间 | 跟踪的起始时间。 |
track_time_to | 否 | 日期时间 | 跟踪的结束时间。 |
push_time_from | 否 | 日期时间 | 推送的起始时间。 |
push_time_to | 否 | 日期时间 | 推送的结束时间。 |
push_status | 否 | 枚举 | 推送结果: NotPushed:没有推送; Success:推送成功; Failure:推送失败; |
push_status_code | 否 | 数值 | 对应 push_status 的代码内容,参考 响应状态码 |
stop_track_time_from | 否 | 日期时间 | 停止跟踪的起始时间。 |
stop_track_time_to | 否 | 日期时间 | 停止跟踪的结束时间。 |
page_no | 否 | 数值 | 页码。 |
order_by | 否 | 枚举 | 排序方式: RegisterTimeAsc: 注册时间升序; RegisterTimeDesc:注册时间降序; PushTimeAsc:推送时间升序; PushTimeDesc:推送时间降序; TrackTimeAsc:查询时间升序; TrackTimeDesc:查询时间降序; |
响应示例
{
"page": {
"data_total": 43,
"page_total": 2,
"page_no": 1,
"page_size": 40
},
"code": 0,
"data": {
"accepted": [
{
"number": "RR123456789CN",
"param": null,
"param_type": "None",
"data_origin": "Api",
"carrier": 3011,
"shipping_country": "CN",
"final_carrier": 0,
"recipient_country": "RU",
"register_time": "2022-03-14T07:45:38Z",
"tracking_status": "Tracking",
"package_status": "Delivered",
"track_time": "2022-03-14T07:45:22Z",
"push_time": "2022-03-14T07:47:42Z",
"push_status": "Success",
"push_status_code":200,
"stop_track_time": "2022-05-12T10:29:03Z",
"stop_track_reason": "ByRequest",
"is_retracked": false,
"carrier_change_count": 1,
"tag": null,
"email":"",
"order_no": "86574382938",
"order_time": "2022-04-25T22:22:47+05:00",
"lang":"",
"remark": "test",
"latest_event_time": "2023-08-05T10:00:21+05:00",
"latest_event_info": "FAISALABAD,Shipment has been Delivered. Delivery Date & Time Aug 5 2023 9:48AM and Received By: Shahzad",
"days_after_order ":2,
"days_after_last_update ":null,
"days_of_transit ":2,
"days_of_transit_done ":2,
"delievery_time": "2023-08-05T05:00:21Z",
"pickup_time": ""
}
]
}
}
响应结果说明:
名称 | 类型 |
描述 |
---|---|---|
page | 对象 | 页码信息 。 |
-data_total | 数值 | 数据总数 。 |
-page_total | 数值 | 页面总数 。 |
-page_no | 数值 | 当前页面索引(默认 0)。 |
-page_size | 数值 | 每页数据总数(默认 40,最大 40)。 |
code | 数值 | 错误状态码 。 |
data | 对象 | 请求对应的响应数据。 |
-accepted | 数组 | 正常处理请求返回结果集合,如果没有满足条件的数据,返回集合为空。 |
--number | 字符串 | 物流单号,需满足 单号格式要求。 |
--param_type | 枚举 | 附加跟踪参数类型。 None : 不需要 PostalCode : 邮编 PhoneLast4Digits : 手机尾号 Alpha-2CountryCode&PostalCode : 国家二字码及邮编 OriginOffice : Origin office Client : Client |
--param | 字符串 | 物流单号附加参数,请参考【注册物流单号】入参说明 |
--data_origin | 枚举 | 单号注册的来源。 Api : 接口 Manual : 添加单号 Import : 表格导入 |
--carrier | 数值 | 运输商代码。 |
--final_carrier | 数值 | 派送物流商代码。 |
--package_status | 字符串 | 包裹状态。 |
--shipping_country | 字符串 | 发件国家。 |
--recipient_country | 字符串 | 收件国家。 |
--register_time | 字符串 | 注册时间。 |
--tracking_status | 字符串 | 跟踪状态: Tracking:自动跟踪; Stopped:停止跟踪; |
--track_time | 字符串 | 最后跟踪时间。 |
--push_time | 字符串 | 最近推送时间。 |
--push_status | 字符串 | 推送结果: NotPushed:没有推送; Success:推送成功; Failure:推送失败; |
--push_status_code | 数值 | 对应 push_status 的代码内容,参考 响应状态码。 |
--stop_track_time | 字符串 | 停止跟踪时间。 |
--stop_track_reason | 字符串 | 停止跟踪原因: Expired:规则过期停止; ByRequest:接口请求停止; InvalidCarrier:运输商无效停止; |
--is_retracked | 布尔值 | 是否重新激活过,false:否;true:是。 |
--carrier_change_count | 数值 | 包裹运输商的修改次数,上限为 5 次。 |
--tag | 字符串 | 自定义标识,最长 100 个字符。如:关联标识,备注分组等。 |
--order_no | 字符串 | 订单号 |
--order_time | 日期时间 | 订单日期 |
字符串 | 客户邮箱 | |
--lang | 字符串 | 翻译语言 |
--remark | 字符串 | 备注 |
--latest_event_time | 日期时间 | 最新事件时间 |
--latest_event_info | 字符串 | 最新事件 |
--days_after_order | 数值 | 运单时效: 签收状态时,间隔天数 = 签收时间 - 第 1 条事件时间 非签收状态且有结果时,间隔天数 = 当前时间 - 第 1 条事件时间 无结果时,间隔天数 = 0 |
--days_after_last_update | 数值 | 信息无更新天数: 签收、退件签收、无结果时,间隔天数 = 0 其它情况时,间隔天数 = 当前时间 - 最后 1 条事件时间 |
--days_of_transit | 数值 | 运输时效: 为签收状态时: 1. 有 InTransit_PickedUp,间隔时间 = 签收时间 - 揽收时间 2. 无 InTransit_PickedUp,有 InfoReceived,间隔时间 = 签收时间 - InfoReceived 后首个事件时间 3. InTransit_PickedUp 和 InfoReceived 都没有,间隔时间 = 签收时间 - 第 1 条事件时间 非签收状态且有轨迹跟踪结果时: 1. 有 InTransit_PickedUp,间隔时间=当前时间 - 揽收时间 2.无 InTransit_PickedUp,有 InfoReceived,间隔时间 = 当前时间 - InfoReceived 后首个事件时间 3. 无 InTransit_PickedUp,有 InfoReceived,但只有 1 条轨迹时,间隔时间 = 0 4. InTransit_PickedUp 和 InfoReceived 都没有, 间隔时间 = 当前时间 - 第 1 条事件时间 无轨迹跟踪结果时:间隔天数 = 0 |
--days_of_transit_done | 数值 | 妥投时效: 为签收状态时: 1. 有 InTransit_PickedUp,间隔时间 = 签收时间 - 揽收时间 2. 无 InTransit_PickedUp,有 InfoReceived,间隔时间 = 签收时间 - InfoReceived 后首个事件时间 3. InTransit_PickedUp 和 InfoReceived 都没有,间隔时间 = 签收时间 - 第 1 条事件时间 非签收状态时:间隔天数 = 0 |
--estimated_delivery_date | 对象 | 预期达到时间信息节点。 |
--delievery_time | 日期时间 | 签收时间 |
--pickup_time | 日期时间 | 揽收时间 |
获取详情
- POST https://api.17track.net/track/v2.2/gettrackinfo
- 该接口每次可提交 40 个物流单号;
- 此接口逻辑与 获取列表接口 一样;
请求示例
curl -X POST \
--header '17token:密钥' \
--header 'Content-Type:application/json' \
--data '[
{
"number": "270434455123",
"carrier": 100003
},
{
"number": "21213123123230",
"carrier": 21051
}
]' \
https://api.17track.net/track/v2.2/gettrackinfo
<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.17track.net/track/v2.2/gettrackinfo",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => "[
{
"number": "270434455123",
"carrier": 100003
},
{
"number": "21213123123230",
"carrier": 21051
}
]",
CURLOPT_HTTPHEADER => [
"17token: 密钥",
"content-type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}
var client = new HttpClient();
var request = new HttpRequestMessage
{
Method = HttpMethod.Post,
RequestUri = new Uri("https://api.17track.net/track/v2.2/gettrackinfo"),
Headers =
{
{ "17token", "密钥" },
},
Content = new StringContent("[
{
"number": "270434455123",
"carrier": 100003
},
{
"number": "21213123123230",
"carrier": 21051
}
]")
{
Headers =
{
ContentType = new MediaTypeHeaderValue("application/json")
}
}
};
using (var response = await client.SendAsync(request))
{
response.EnsureSuccessStatusCode();
var body = await response.Content.ReadAsStringAsync();
Console.WriteLine(body);
}
OkHttpClient client = new OkHttpClient();
MediaType mediaType = MediaType.parse("application/json");
String value = "[
{
"number": "270434455123",
"carrier": 100003
},
{
"number": "21213123123230",
"carrier": 21051
}
]";
RequestBody body = RequestBody.create(mediaType, value);
Request request = new Request.Builder()
.url("https://api.17track.net/track/v2.2/gettrackinfo")
.post(body)
.addHeader("content-type", "application/json")
.addHeader("17token", "密钥")
.build();
Response response = client.newCall(request).execute();
response.body();
const axios = require("axios");
const options = {
method: 'POST',
url: 'https://api.17track.net/track/v2.2/gettrackinfo',
headers: {
'content-type': 'application/json',
'17token': '密钥'
},
data: '[
{
"number": "270434455123",
"carrier": 100003
},
{
"number": "21213123123230",
"carrier": 21051
}
]'
};
axios.request(options).then(function (response) {
console.log(response.data);
}).catch(function (error) {
console.error(error);
});
import requests
url = "https://api.17track.net/track/v2.2/gettrackinfo"
payload = [
{
"number": "270434455123",
"carrier": 100003
},
{
"number": "21213123123230",
"carrier": 21051
}
]
headers = {
"content-type": "application/json",
"17token": "密钥"
}
response = requests.request("POST", url, json=payload, headers=headers)
print(response.text)
请求参数说明:
名称 | 是否必须 |
类型 |
描述 |
---|---|---|---|
number | 是 | 字符串 | 物流单号,需满足 单号格式要求。 |
carrier | 否 | 数值 | 运输商代码,不传的时候如果有多条相同单号的数据(运输商不同),则处理多条。 |
响应示例
{
"code": 0,
"data": {
"accepted": [
{
"number": "RR123465789CN",
"carrier": 100003,
"param": "232296506",
"tag": "myID",
"track_info": {
"shipping_info": {
"shipper_address": {
"country": "CN",
"state": "GD",
"city": "SHENZHEN",
"street": "HARTFORD CT DISTRIBUTION CENTER",
"postal_code": "518000",
"coordinates": {
"longitude": "114.085947",
"latitude": "22.547"
}
},
"recipient_address": {
"country": "AF",
"state": null,
"city": "KABUL",
"street": null,
"postal_code": null,
"coordinates": {
"longitude": null,
"latitude": null
}
}
},
"latest_status": {
"status": "InfoReceived",
"sub_status": "InfoReceived",
"sub_status_descr": null
},
"latest_event": {
"time_iso": "2022-03-02T20:43:24-06:00",
"time_utc": "2022-03-03T02:43:24Z",
"time_raw": {
"date": "2022-03-02",
"time": "20:43:24",
"timezone": "-06:00"
},
"description": "Shipment information sent to FedEx",
"description_translation": {
"lang": "en",
"description": "Shipment information sent to FedEx"
},
"location": "NJ",
"stage": "InfoReceived",
"sub_status": "InfoReceived",
"address": {
"country": "US",
"state": "NJ",
"city": "MARLTON",
"street": null,
"postal_code": "08053",
"coordinates": {
"longitude": null,
"latitude": null
}
}
},
"time_metrics": {
"days_after_order": 7,
"days_of_transit": 7,
"days_of_transit_done": 7,
"days_after_last_update": 57,
"estimated_delivery_date": {
"source":"Official",
"from": "2021-09-01T08:00:54-05:00",
"to": "2021-09-01T13:00:45-05:00"
}
},
"milestone": [
{
"key_stage": "InfoReceived",
"time_iso": "2023-08-14T00:00:00-05:00",
"time_utc": "2023-08-14T05:00:00Z",
"time_raw": {
"date": "2023-08-14",
"time": null,
"timezone": null
}
},
{
"key_stage": "PickedUp",
"time_iso": "2023-08-15T08:46:00-05:00",
"time_utc": "2023-08-15T12:46:00Z",
"time_raw": {
"date": "2023-08-15",
"time": "08:46:00",
"timezone": "-05:00"
}
},
{
"key_stage": "Departure",
"time_iso": null,
"time_utc": null,
"time_raw": {
"date": null,
"time": null,
"timezone": null
}
},
{
"key_stage": "Arrival",
"time_iso": null,
"time_utc": null,
"time_raw": {
"date": null,
"time": null,
"timezone": null
}
},
{
"key_stage": "AvailableForPickup",
"time_iso": null,
"time_utc": null,
"time_raw": {
"date": null,
"time": null,
"timezone": null
}
},
{
"key_stage": "OutForDelivery",
"time_iso": null,
"time_utc": null,
"time_raw": {
"date": null,
"time": null,
"timezone": null
}
},
{
"key_stage": "Delivered",
"time_iso": null,
"time_utc": null,
"time_raw": {
"date": null,
"time": null,
"timezone": null
}
},
{
"key_stage": "Returning",
"time_iso": null,
"time_utc": null,
"time_raw": {
"date": null,
"time": null,
"timezone": null
}
},
{
"key_stage": "Returned",
"time_iso": null,
"time_utc": null,
"time_raw": {
"date": null,
"time": null,
"timezone": null
}
}
],
"misc_info": {
"risk_factor": 0,
"service_type": "FedEx International Priority",
"weight_raw": "1.1 KG",
"weight_kg": "1.1",
"pieces": "1",
"dimensions": "22*20*16 CM",
"customer_number": "2459642000~270434455123~FX",
"reference_number": null,
"local_number": "270434455123",
"local_provider": "Fedex",
"local_key": 100003
},
"tracking": {
"providers_hash": 182180920,
"providers": [
{
"provider": {
"key": 100003,
"name": "Fedex",
"alias": "Fedex",
"tel": null,
"homepage": "http://www.fedex.com/",
"country": "TR"
},
"service_type": "FedEx International Priority",
"latest_sync_status": "Success",
"latest_sync_time": "2022-04-28T02:37:03Z",
"events_hash": -731027172,
"events": [
{
"time_iso": "2023-08-14T00:00:00-05:00",
"time_utc": "2023-08-14T05:00:00Z",
"time_raw": {
"date": "2023-08-14",
"time": null,
"timezone": null
},
"description": "At local FedEx facility",
"description_translation": {
"lang": "en",
"description": "At local FedEx facility"
},
"location": "ANCHORAGE, AK, US",
"stage": "InfoReceived",
"sub_status": "InfoReceived",
"address": {
"country": "US",
"state": "AK",
"city": "ANCHORAGE",
"street": null,
"postal_code": "99502",
"coordinates": {
"longitude": "35.86166",
"latitude": "104.195397"
}
}
}
]
},
{
"provider": {
"key": 1151,
"name": "Australia Post",
"alias": "Australia Post",
"tel": null,
"homepage": "http://auspost.com.au/",
"country": "AU"
},
"service_type": "International Post Express",
"latest_sync_status": "Success",
"latest_sync_time": "2022-04-12T22:12:54Z",
"events_hash": -225868020,
"events": [
{
"time_iso": "2022-03-04T15:33:00+08:00",
"time_utc": "2022-03-04T07:33:00Z",
"time_raw": {
"date": "2022-03-04",
"time": "15:33:00",
"timezone": null
},
"description": "InfoReceived",
"description_translation": {
"lang": "en",
"description": "InfoReceived"
},
"location": null,
"stage": "InfoReceived",
"sub_status": "InfoReceived",
"address": {
"country": null,
"state": null,
"city": null,
"street": null,
"postal_code": null,
"coordinates": {
"longitude": null,
"latitude": null
}
}
}
]
}
]
}
}
}
],
"rejected": [
{
"number": "21213123123230",
"error": {
"code": -18019910,
"message": "The carrier's value '21051' is not correct."
}
}
]
}
}
响应结果说明:
名称 |
类型 |
描述 |
---|---|---|
code | 数值 | 错误状态码 。 |
data | 对象 | 请求对应的响应数据。 |
-accepted | 数组 | 正常处理请求返回结果集合,如果没有满足条件的数据,返回集合为空。 |
--number | 字符串 | 物流单号。 |
--carrier | 数值 | 运输商代码。 |
--param | 字符串 | 物流单号附加参数,请参考【注册物流单号】入参说明 |
--tag | 字符串 | 自定义标签,最长 100 个字符。如:关联标识,备注分组等。 |
--track_info | 对象 | 物流信息主结构节点。 |
---shipping_info | 对象 | 地区相关信息节点。 |
----shipper_address | 对象 | 发件地信息节点。 |
-----country | 字符串 | 国家或地区(大写)。 |
-----state | 字符串 | 州、省。 |
-----postal_code | 字符串 | 邮编。 |
-----city | 字符串 | 城市。 |
-----street | 字符串 | 街道。 |
-----coordinates | 对象 | 位置坐标(如经度纬度)。 |
------longitude | 字符串 | 经度。 |
------latitude | 字符串 | 纬度。 |
----recipient_address | 对象 | 收件地信息节点。 |
-----country | 字符串 | 国家或地区(大写)。 |
-----state | 字符串 | 州、省。 |
-----postal_code | 字符串 | 邮编。 |
-----city | 字符串 | 城市。 |
-----street | 字符串 | 街道。 |
-----coordinates | 对象 | 位置坐标(如经度纬度)。 |
------longitude | 字符串 | 经度。 |
------latitude | 字符串 | 纬度。 |
---latest_status | 对象 | 最新状态节点。 |
----status | 字符串 | 物流主状态。 |
----sub_status | 字符串 | 包裹子状态。 |
----sub_status_descr | 字符串 | 状态描述。 |
---latest_event | 对象 | 最新事件,信息结构与描述参考 events 集合。 |
---time_metrics | 对象 | 时效相关信息节点,其中 estimated_delivery_date 为时间区间。 |
----days_after_order | 数值 | 运单时效: 签收状态时,间隔天数 = 签收时间 - 第 1 条事件时间 非签收状态且有结果时,间隔天数 = 当前时间 - 第 1 条事件时间 无结果时,间隔天数 = 0 |
----days_after_last_update | 数值 | 信息无更新天数: 签收、退件签收、无结果时,间隔天数 = 0 其它情况时,间隔天数 = 当前时间 - 最后 1 条事件时间 |
----days_of_transit | 数值 | 运输时效: 为签收状态时: 1. 有 InTransit_PickedUp,间隔时间 = 签收时间 - 揽收时间 2. 无 InTransit_PickedUp,有 InfoReceived,间隔时间 = 签收时间 - InfoReceived 后首个事件时间 3. InTransit_PickedUp 和 InfoReceived 都没有,间隔时间 = 签收时间 - 第 1 条事件时间 非签收状态且有轨迹跟踪结果时: 1. 有 InTransit_PickedUp,间隔时间=当前时间 - 揽收时间 2.无 InTransit_PickedUp,有 InfoReceived,间隔时间 = 当前时间 - InfoReceived 后首个事件时间 3. 无 InTransit_PickedUp,有 InfoReceived,但只有 1 条轨迹时,间隔时间 = 0 4. InTransit_PickedUp 和 InfoReceived 都没有, 间隔时间 = 当前时间 - 第 1 条事件时间 无轨迹跟踪结果时:间隔天数 = 0 |
----days_of_transit_done | 数值 | 妥投时效: 为签收状态时: 1. 有 InTransit_PickedUp,间隔时间 = 签收时间 - 揽收时间 2. 无 InTransit_PickedUp,有 InfoReceived,间隔时间 = 签收时间 - InfoReceived 后首个事件时间 3. InTransit_PickedUp 和 InfoReceived 都没有,间隔时间 = 签收时间 - 第 1 条事件时间 非签收状态时:间隔天数 = 0 |
----estimated_delivery_date | 对象 | 预期达到时间信息节点。 |
-----source | 字符串 | 表示 from 和 to 的内容提供者,17TRACK 表示 17TRACK 提供,Official 表示由运输商官方提供,null 表示没有提供者。 |
------from | 字符串 | 预计投递最早时间(ISO 格式),例如:2021-09-01T08:00:54-05:00。 |
------to | 字符串 | 预计投递最晚时间(ISO 格式),例如:2021-09-01T08:00:54-05:00。 |
---milestone | 数组 | 里程碑 作用:展示承运过程中的主要节点及发生顺序和时间 用法:遍历 milestone 各项,建议顺序为:InfoReceived >> PickedUp >> Departure >> Arrival >> OutForDelivery >> Delivered。 (AvailableForPickup、Returned、Returning 按具体情况使用) 注意:如果 time_iso 或 time_utc 为 null,则表示运输商未提供事件描述。可以用 milestone[].key_stage 在 tracking.providers[].events[].stage 中查询比较具体事件内容。 milestone 的 key_stage 含义: InfoReceived:收到信息,运输商收到商家的下单信息,等待上门取件。 PickedUp:揽收,运输商收取商家的包裹。 Departure:离港,离开发件国港口(理论上是清关后的动作)。 Arrival:到港,到达收件国港口(是否有清关并不确定)。 AvailableForPickup:到达待取,包裹已经到达目的地的投递点,需要收件人自取。 OutForDelivery:派送途中,包裹正在投递过程中。 Delivered:成功签收,包裹已妥投。 Returned:退件,包裹已经完成退件操作。 Returning:退件中,包裹在处理,但不保证处理完会转成"退件"状态。 |
----key_stage | 字符串 | 里程碑,对应 tracking.providers[].provider[].events[].stage。 |
----time_iso | 字符串 | 1. 状态发生的时间(ISO 格式),由运输商当地时间转换得出带时区的格式,当时间格式错误则显示原始时间; 2. 上游运输商有时区信息则优先使用,没有按运输商总部所在的时区使用; 3. 例如:2022-03-02T20:43:24-06:00,表示当前为西6区; 4. 把(-06:00)时区信息去掉则为运输商当地时间; 5. 此值对应事件集合中的 time_iso,即: tracking.providers[].provider[].events[].time_iso; |
----time_utc | 字符串 | 1. 状态发生的时间(UTC 格式),由 time_iso 转换得来,time_iso 无效则显示为 null。 2. 例如:2022-03-03T02:43:24Z; 3. 此值对应事件集合中的 time_utc,即: tracking.providers[].provider[].events[].time_utc; |
----time_raw | 对象 | 运输商提供的原始时间信息, 1. 共三组分别是:年月日、时分秒、时区。 2. 如果是 null,则表示运输商没有提供数据。 |
-----date | 字符串 | 年月日信息 |
-----time | 字符串 | 时分秒信息 |
-----timezone | 字符串 | 时区信息,如果 timezone 是 null,time_iso 是有效的时间则表示是由 17TRACK 补充的时区信息。 |
---misc_info | 对象 | 包裹附属信息节点。 |
----risk_factor | 字符串 | 包裹风险系数。 |
----service_type | 字符串 | 服务类型。 |
----weight_raw | 字符串 | 原始重量信息,返回的重量单位根据运输商提供,有可能是克、公斤、磅等。 |
----weight_kg | 字符串 | 把原始重量信息( weight_raw) 转换为公斤。 |
----pieces | 字符串 | 件数。 |
----dimensions | 字符串 | 原始体积尺寸(长宽高),不同运输商可能会存在不同的类型,目前大多数运输商使用的是cm单位。 |
----customer_number | 字符串 | 收货客户单号。 |
----reference_number | 字符串 | 参考号。 |
----local_number | 字符串 | 尾程单号。 |
----local_provider | 字符串 | 尾程运输商。 |
----local_key | 数值 | 尾程运输商代码。 |
---tracking | 对象 | 物流信息节点。 |
----providers_hash | 数值 | 哈希值,根据事件内容计算出来,用于判断是否有变更。 |
----providers | 数组 | 运输商集合节点 特别情况说明:当包裹是邮政承运时,providers[0] 对象表示目的地运输商信息,providers[1] 对象表示发件地运输商信息,有可能会出现 providers[0] 和 providers[1] 的轨迹描述、时间有重复的情况。 |
-----provider | 对象 | 运输商信息节点。 |
------key | 数值 | 运输商代码。 |
------name | 字符串 | 运输商名称。 |
------alias | 字符串 | 运输商别名。 |
------tel | 字符串 | 运输商联系电话。 |
------homepage | 字符串 | 运输商官网。 |
------country | 字符串 | 运输商所属国家。 |
-----service_type | 字符串 | 服务类型。 |
-----latest_sync_status | 字符串 | 最近同步状态, Failure:同步失败; Success:同步成功; |
-----latest_sync_time | 字符串 | 最近同步时间。 |
-----events_hash | 数值 | 事件哈希值。 |
-----events | 数组 | 事件集合节点。 每一项为物流事件对象,顺序是按事件时间倒序排列,离当前时间越近越靠前。 |
------time_iso | 字符串 | 1. 事件发生时间(ISO 格式),由运输商当地时间转换得出带时区的格式,当时间格式错误则显示原始时间; 2. 上游运输商有时区信息则优先使用,没有按运输商总部所在的时区使用; 3. 例如:2022-03-02T20:43:24-06:00,表示当前为西6区; 4. 把(-06:00)时区信息去掉则为运输商当地时间; |
------time_utc | 字符串 | 1. 事件发生时间(UTC 时间),由 time_iso 转换得来,time_iso 无效则显示为 null。 2. 例如:2022-03-03T02:43:24Z; |
------time_raw | 对象 | 运输商提供的原始时间信息, 1. 共三组分别是:年月日、时分秒、时区。 2. 如果是 null,则表示运输商没有提供数据。 |
-------date | 字符串 | 年月日信息 |
-------time | 字符串 | 时分秒信息 |
-------timezone | 字符串 | 时区信息,null表示未提供,如果timezone是null,time_iso是有效时间则表示是有17TRACK补充的时区信息 |
------description | 字符串 | 事件描述,包括:事件发生的地点、承运中行为、关键状态说明。 |
------description_translation | 对象 | 描述翻译节点。 |
-------description | 字符串 | 翻译后的事件描述。 |
-------lang | 字符串 | 翻译语言代码 |
------location | 字符串 | 地点。 |
------stage | 字符串 | 里程碑状态,不保证一定会有状态信息,取决于上游运输商数据情况。 |
------sub_status | 字符串 | 包裹子状态。 |
------address | 对象 | 地点信息节点。 |
-------country | 字符串 | 国家地区。 |
-------state | 字符串 | 州、省。 |
-------city | 字符串 | 城市。 |
-------street | 字符串 | 街道。 |
-------postal_code | 字符串 | 邮编。 |
-------coordinates | 对象 | 位置坐标信息节点。 |
--------longitude | 字符串 | 经度。 |
--------latitude | 字符串 | 纬度。 |
-rejected | 数组 | 拒绝接受请求的单号信息集合。 |
--number | 字符串 | 物流单号。 |
--error | 对象 | 错误信息集合。 |
--code | 数值 | 错误提示代码,具体错误原因可以检查对应的 错误代码 |
--message | 字符串 | 错误代码描述。 |
手动推送
- POST https://api.17track.net/track/v2.2/push
- 该接口每次可提交 40 个物流单号;
- 成功提交接口后对应物流单号会进入任务队列,由全局调度发起推送;
请求示例
curl -X POST \
--header '17token:密钥' \
--header 'Content-Type:application/json' \
--data '[
{
"number": "RR123456789CN",
"carrier": 3011
},
{
"number": "21213123123230",
"carrier": 21051
}
]' \
https://api.17track.net/track/v2.2/push
<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.17track.net/track/v2.2/push",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => "[
{
"number": "RR123456789CN",
"carrier": 3011
},
{
"number": "21213123123230",
"carrier": 21051
}
]",
CURLOPT_HTTPHEADER => [
"17token: 密钥",
"content-type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}
var client = new HttpClient();
var request = new HttpRequestMessage
{
Method = HttpMethod.Post,
RequestUri = new Uri("https://api.17track.net/track/v2.2/push"),
Headers =
{
{ "17token", "密钥" },
},
Content = new StringContent("[
{
"number": "RR123456789CN",
"carrier": 3011
},
{
"number": "21213123123230",
"carrier": 21051
}
]")
{
Headers =
{
ContentType = new MediaTypeHeaderValue("application/json")
}
}
};
using (var response = await client.SendAsync(request))
{
response.EnsureSuccessStatusCode();
var body = await response.Content.ReadAsStringAsync();
Console.WriteLine(body);
}
OkHttpClient client = new OkHttpClient();
MediaType mediaType = MediaType.parse("application/json");
String value = "[
{
"number": "RR123456789CN",
"carrier": 3011
},
{
"number": "21213123123230",
"carrier": 21051
}
]";
RequestBody body = RequestBody.create(mediaType, value);
Request request = new Request.Builder()
.url("https://api.17track.net/track/v2.2/push")
.post(body)
.addHeader("content-type", "application/json")
.addHeader("17token", "密钥")
.build();
Response response = client.newCall(request).execute();
response.body();
const axios = require("axios");
const options = {
method: 'POST',
url: 'https://api.17track.net/track/v2.2/push',
headers: {
'content-type': 'application/json',
'17token': '密钥'
},
data: '[
{
"number": "RR123456789CN",
"carrier": 3011
},
{
"number": "21213123123230",
"carrier": 21051
}
]'
};
axios.request(options).then(function (response) {
console.log(response.data);
}).catch(function (error) {
console.error(error);
});
import requests
url = "https://api.17track.net/track/v2.2/push"
payload = [
{
"number": "RR123456789CN",
"carrier": 3011
},
{
"number": "21213123123230",
"carrier": 21051
}
]
headers = {
"content-type": "application/json",
"17token": "密钥"
}
response = requests.request("POST", url, json=payload, headers=headers)
print(response.text)
请求参数说明:
名称 | 是否必须 |
类型 |
描述 |
---|---|---|---|
number | 是 | 字符串 | 物流单号需满足 单号格式要求。 |
carrier | 否 | 数值 | 运输商代码,不传的时候如果有多条相同单号的数据(运输商不同),则处理多条。 |
响应示例
{
"code": 0,
"data": {
"accepted": [
{
"number": "RR123456789CN",
"carrier": 3011
}
],
"rejected": [
{
"number": "21213123123230",
"error": {
"code": -18019909,
"message": "No tracking information at this time."
}
}
]
}
}
响应结果说明:
名称 | 类型 |
描述 |
---|---|---|
code | 数值 | 错误代码。 |
data | 对象 | 请求对应的响应数据。 |
-accepted | 数组 | 正常接受并处理的请求。 |
--number | 字符串 | 物流单号。 |
--carrier | 数值 | 运输商代码。 |
-rejected | 数组 | 拒绝接受请求的单号信息集合。 |
--number | 字符串 | 物流单号。 |
--error | 对象 | 错误信息集合。 |
--code | 数值 | 错误提示代码,具体错误原因可以检查对应的 错误代码 |
--message | 字符串 | 错误代码描述。 |
实时查询
- POST https://api.17track.net/track/v2.2/getRealTimeTrackInfo
- 若物流单号number未注册,响应的结果不会保存到当前账号中;若number已订阅且本次查询结果有变化则会触发推送(webhook);
- 截止目前以下运输商不支持通过此接口进行实时查询:
运输商名称 | 运输商代码 |
---|---|
USPS | 21051 |
Royal Mail | 11031 |
Australia post | 1151 |
Direct Freight Express | 101066 |
DHL eCommerce US | 7047 |
DHL Global Forwarding | 100766 |
- 接⼝请求超时上限 30 秒;
- 此接口提供两种查询模式,两种模式查询时效不同,额度扣取规则不同。
当请求参数cacheLevel=0,表⽰获取最近 3⼩时内的运输商物流信息(默认值),⼤部分⽤⼾选择的⼿动刷新⽅式,每次扣减1个额度。
当请求参数cacheLevel=1,表⽰⻢上发启抓取动作,获取当前运输商物流信息,最及时的刷新⽅式,每次扣减 10个额度。
请求示例
curl -X POST \
--header '17token:密钥' \
--header 'Content-Type:application/json' \
--data '[
{
"number": "RR123456789CN",
"carrier": 3011
}
]' \
https://api.17track.net/track/v2.2/getRealTimeTrackInfo
<?php
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://api.17track.net/track/v2.2/getRealTimeTrackInfo',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS =>'[
{
"number": "RR123456789CN",
"carrier":3011
}
]
',
CURLOPT_HTTPHEADER => array(
'content-type: application/json',
'17token: 密钥'
),
));
$response = curl_exec($curl);
curl_close($curl);
echo $response;
var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Post, "https://api.17track.net/track/v2.2/getRealTimeTrackInfo");
request.Headers.Add("content-type", "application/json");
request.Headers.Add("17token", "密钥");
var content = new StringContent("[\r\n {\r\n \"number\": \"RR123456789CN\",\r\n \"carrier\":3011\r\n }\r\n]\r\n ", null, "application/json");
request.Content = content;
var response = await client.SendAsync(request);
response.EnsureSuccessStatusCode();
Console.WriteLine(await response.Content.ReadAsStringAsync());
OkHttpClient client = new OkHttpClient().newBuilder()
.build();
MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "[\r\n {\r\n \"number\": \"RR123456789CN\",\r\n \"carrier\":3011\r\n }\r\n]\r\n ");
Request request = new Request.Builder()
.url("https://api.17track.net/track/v2.2/getRealTimeTrackInfo")
.method("POST", body)
.addHeader("content-type", "application/json")
.addHeader("17token", "密钥")
.build();
Response response = client.newCall(request).execute();
const axios = require('axios');
let data = JSON.stringify([
{
"number": "RR123456789CN",
"carrier": 3011
}
]);
let config = {
method: 'post',
maxBodyLength: Infinity,
url: 'https://api.17track.net/track/v2.2/getRealTimeTrackInfo',
headers: {
'content-type': 'application/json',
'17token': '密钥'
},
data : data
};
axios.request(config)
.then((response) => {
console.log(JSON.stringify(response.data));
})
.catch((error) => {
console.log(error);
});
import requests
import json
url = "https://api.17track.net/track/v2.2/getRealTimeTrackInfo"
payload = json.dumps([
{
"number": "RR123456789CN",
"carrier": 3011
}
])
headers = {
'content-type': 'application/json',
'17token': '密钥'
}
response = requests.request("POST", url, headers=headers, data=payload)
print(response.text)
请求参数说明:
参数名称 | 是否必须 |
类型 |
描述 |
---|---|---|---|
number | 是 | 字符串 | 物流单号需满足 单号格式要求。 |
param | 否 | 字符串 | 物流单号附加跟踪参数(较少的运输商要求提供邮编或下单日期才能查询包裹信息); |
carrier | 否 | 数值 | 运输商代码: 1. 系统可以识别大多数万国邮联(UPU)或合作运输商的定制物流单号(无需指定运输商代码),如果传错系统会进行纠正并返回正确的 运输商代码; 2. 指定运输商进行注册成功后返回的 物流主状态是查询不到,则可能是数据未上网、运输商服务异常、指定错运输商等情况; 3. 返回错误代码 -18019903 表示系统无法识别物流单号所属运输商; 4. 因注册成功后会扣减单量,建议您明确物流单号所对应的 运输商 再进行操作; 5. 因指定错的运输商注册成功的物流单号,可以使用 修改运输商接口调整; |
final_carrier | 否 | 数值 | 尾程运输商代码(仅支持邮政渠道)。 |
auto_detection | 否 | 布尔值 | 是否开启运输商自动检测,默认为 true,但是不确保一定可以识别到且不保证识别结果的准确性,如果用户有传入有效的 carrier 参数,则该参数无效。 |
cacheLevel | 否 | 数值 | 17TRACK 提供两种查询模式: 0,表⽰获取最近 3⼩时内的运输商物流信息(默认值),⼤部⽤⼾选择的⼿动刷新⽅式,每次扣减1 1,表⽰⻢上发启抓取动作,获取当前运输商物流信息,最及时的刷新⽅式,每次扣减 10个额度。 |
响应示例
{
"code": 0,
"data": {
"accepted": [
{
"number": "RR123456789CN",
"carrier": 3011,
"param": null,
"tag": "",
"track_info": {
"shipping_info": {
"shipper_address": {
"country": "CN",
"state": null,
"city": null,
"street": null,
"postal_code": null,
"coordinates": {
"longitude": null,
"latitude": null
}
},
"recipient_address": {
"country": "",
"state": null,
"city": null,
"street": null,
"postal_code": null,
"coordinates": {
"longitude": null,
"latitude": null
}
}
},
"latest_status": {
"status": "NotFound",
"sub_status": "NotFound_Other",
"sub_status_descr": null
},
"latest_event": null,
"time_metrics": {
"days_after_order": 0,
"days_of_transit": 0,
"days_of_transit_done": 0,
"days_after_last_update": 0,
"estimated_delivery_date": {
"source": null,
"from": null,
"to": null
}
},
"milestone": [],
"misc_info": {
"risk_factor": 0,
"service_type": null,
"weight_raw": null,
"weight_kg": null,
"pieces": null,
"dimensions": null,
"customer_number": null,
"reference_number": null,
"local_number": null,
"local_provider": null,
"local_key": 0
},
"tracking": {
"providers_hash": 0,
"providers": [
{
"provider": {
"key": 3011,
"name": "China Post",
"alias": "China Post 中国邮政",
"tel": "",
"homepage": "https://yjcx.ems.com.cn/",
"country": "CN"
},
"provider_lang": null,
"service_type": null,
"latest_sync_status": "Success",
"latest_sync_time": "2024-12-10T14:14:42Z",
"events_hash": 0,
"events": []
}
]
}
}
}
],
"rejected": []
}
}
响应结果说明:
名称 | 类型 |
描述 |
---|---|---|
code | 数值 | 错误代码。 |
data | 对象 | 单号的跟踪详情,与 gettrackinfo接口 响应报文 accepted 结构一样。 |
-number | 字符串 | 物流单号。 |
-carrier | 数值 | 运输商代码。 |
-param | 字符串 | 物流单号附加参数,请参考【注册物流单号】入参说明 |
-tag | 字符串 | 自定义标签,最长 100 个字符。如:关联标识,备注分组等。 |
-track_info | 对象 | 物流信息主结构节点。 |
--shipping_info | 对象 | 地区相关信息节点。 |
---shipper_address | 对象 | 发件地信息节点。 |
-----raw | 对象 | 原始信息。 |
------country | 字符串 | 国家或地区(大写)。 |
------state | 字符串 | 州、省。 |
------postal_code | 字符串 | 邮编。 |
------city | 字符串 | 城市。 |
------street | 字符串 | 街道。 |
------coordinates | 对象 | 位置坐标(如经度纬度)。 |
-------longitude | 字符串 | 经度。 |
-------latitude | 字符串 | 纬度。 |
----country | 字符串 | 国家或地区(大写)。 |
----state | 字符串 | 州、省。 |
----postal_code | 字符串 | 邮编。 |
----city | 字符串 | 城市。 |
----street | 字符串 | 街道。 |
----coordinates | 对象 | 位置坐标(如经度纬度)。 |
-----longitude | 字符串 | 经度。 |
-----latitude | 字符串 | 纬度。 |
---recipient_address | 对象 | 收件地信息节点。 |
-----raw | 对象 | 原始信息。 |
------country | 字符串 | 国家或地区(大写)。 |
------state | 字符串 | 州、省。 |
------postal_code | 字符串 | 邮编。 |
------city | 字符串 | 城市。 |
------street | 字符串 | 街道。 |
------coordinates | 对象 | 位置坐标(如经度纬度)。 |
-------longitude | 字符串 | 经度。 |
-------latitude | 字符串 | 纬度。 |
----country | 字符串 | 国家或地区(大写)。 |
----state | 字符串 | 州、省。 |
----postal_code | 字符串 | 邮编。 |
----city | 字符串 | 城市。 |
----street | 字符串 | 街道。 |
----coordinates | 对象 | 位置坐标(如经度纬度)。 |
-----longitude | 字符串 | 经度。 |
-----latitude | 字符串 | 纬度。 |
--latest_status | 对象 | 最新状态节点。 |
---status | 字符串 | 物流主状态。 |
---sub_status | 字符串 | 包裹子状态。 |
---sub_status_descr | 字符串 | 状态描述。 |
--latest_event | 对象 | 最新事件,信息结构与描述参考 events 集合。 |
--time_metrics | 对象 | 时效相关信息节点,其中 estimated_delivery_date 为时间区间。 |
---days_after_order | 数值 | 运单时效: 签收状态时,间隔天数 = 签收时间 - 第 1 条事件时间 非签收状态且有结果时,间隔天数 = 当前时间 - 第 1 条事件时间 无结果时,间隔天数 = 0 |
---days_after_last_update | 数值 | 信息无更新天数: 签收、退件签收、无结果时,间隔天数 = 0 其它情况时,间隔天数 = 当前时间 - 最后 1 条事件时间 |
---days_of_transit | 数值 | 运输时效: 为签收状态时: 1. 有 InTransit_PickedUp,间隔时间 = 签收时间 - 揽收时间 2. 无 InTransit_PickedUp,有 InfoReceived,间隔时间 = 签收时间 - InfoReceived 后首个事件时间 3. InTransit_PickedUp 和 InfoReceived 都没有,间隔时间 = 签收时间 - 第 1 条事件时间 非签收状态且有轨迹跟踪结果时: 1. 有 InTransit_PickedUp,间隔时间=当前时间 - 揽收时间 2.无 InTransit_PickedUp,有 InfoReceived,间隔时间 = 当前时间 - InfoReceived 后首个事件时间 3. 无 InTransit_PickedUp,有 InfoReceived,但只有 1 条轨迹时,间隔时间 = 0 4. InTransit_PickedUp 和 InfoReceived 都没有, 间隔时间 = 当前时间 - 第 1 条事件时间 无轨迹跟踪结果时:间隔天数 = 0 |
---days_of_transit_done | 数值 | 妥投时效: 为签收状态时: 1. 有 InTransit_PickedUp,间隔时间 = 签收时间 - 揽收时间 2. 无 InTransit_PickedUp,有 InfoReceived,间隔时间 = 签收时间 - InfoReceived 后首个事件时间 3. InTransit_PickedUp 和 InfoReceived 都没有,间隔时间 = 签收时间 - 第 1 条事件时间 非签收状态时:间隔天数 = 0 |
---estimated_delivery_date | 对象 | 预期达到时间信息节点。 |
----source | 字符串 | 表示 from 和 to 的内容提供者,17TRACK 表示 17TRACK 提供,Official 表示由运输商官方提供,null 表示没有提供者。 |
----from | 字符串 | 预计投递最早时间(ISO 格式),例如:2021-09-01T08:00:54-05:00。 |
----to | 字符串 | 预计投递最晚时间(ISO 格式),例如:2021-09-01T08:00:54-05:00。 |
---milestone | 数组 | 里程碑 作用:展示承运过程中的主要节点及发生时间 用法:遍历 milestone 各项,建议顺序为:InfoReceived >> PickedUp >> Departure >> Arrival >> OutForDelivery >> Delivered。 (AvailableForPickup、Returned、Returning 按具体情况使用) 注意:如果 time_iso 或 time_utc 为 null,则表示运输商未提供事件描述。可以用 milestone[].key_stage 在 tracking.providers[].events[].stage 中查询比较具体事件内容。 milestone 的 key_stage 含义: InfoReceived:收到信息,运输商收到商家的下单信息,等待上门取件。 PickedUp:揽收,运输商收取商家的包裹。 Departure:离港,离开发件国港口(理论上是清关后的动作)。 Arrival:到港,到达收件国港口(是否有清关并不确定)。 AvailableForPickup:到达待取,包裹已经到达目的地的投递点,需要收件人自取。 OutForDelivery:派送途中,包裹正在投递过程中。 Delivered:成功签收,包裹已妥投。 Returned:退件,包裹已经完成退件操作。 Returning:退件中,包裹在处理,但不保证处理完会转成"退件"状态。 |
---key_stage | 字符串 | 里程碑状态,不保证一定会有状态信息,取决于上游运输商数据情况。 |
---time_iso | 字符串 | 1. 状态发生的时间(ISO 格式),由运输商当地时间转换得出带时区的格式,当时间格式错误则显示原始时间; 2. 上游运输商有时区信息则优先使用,没有按运输商总部所在的时区使用; 3. 例如:2022-03-02T20:43:24-06:00,表示当前为西6区; 4. 把(-06:00)时区信息去掉则为运输商当地时间; 5. 此值对应事件集合中的 time_iso,即: tracking.providers[].provider[].events[].time_iso; |
---time_utc | 字符串 | 1. 状态发生的时间(UTC 格式),由 time_iso 转换得来,time_iso 无效则显示为 null。 2. 例如:2022-03-03T02:43:24Z; 3. 此值对应事件集合中的 time_utc,即: tracking.providers[].provider[].events[].time_utc; |
---time_raw | 对象 | 运输商提供的原始时间信息, 1. 共三组分别是:年月日、时分秒、时区。 2. 如果是 null,则表示运输商没有提供数据。 |
----date | 字符串 | 年月日信息 |
----time | 字符串 | 时分秒信息 |
----timezone | 字符串 | 时区信息,如果 timezone 是 null,time_iso 是有效的时间则表示是由 17TRACK 补充的时区信息。 |
--misc_info | 对象 | 包裹附属信息节点。 |
---risk_factor | 字符串 | 包裹风险系数。 |
---service_type | 字符串 | 服务类型。 |
---weight_raw | 字符串 | 原始重量信息,返回的重量单位根据运输商提供,有可能是克、公斤、磅等。 |
---weight_kg | 字符串 | 把原始重量信息( weight_raw) 转换为公斤。 |
---pieces | 字符串 | 件数。 |
---dimensions | 字符串 | 原始体积尺寸(长宽高),不同运输商可能会存在不同的类型,目前大多数运输商使用的是cm单位。 |
---customer_number | 字符串 | 收货客户单号。 |
---reference_number | 字符串 | 参考号。 |
---local_number | 字符串 | 尾程单号。 |
---local_provider | 字符串 | 尾程运输商。 |
---local_key | 数值 | 尾程运输商代码。 |
--tracking | 对象 | 物流信息节点。 |
---providers_hash | 数值 | 哈希值,根据事件内容计算出来,用于判断是否有变更。 |
---providers | 数组 | 运输商集合节点 特别情况说明:当前包裹是邮政承运时,providers[1] 对象表示目的地运输商信息,providers[0] 对象表示发件地运输商信息,有可能会出现 providers[0] 和 providers[1] 的轨迹描述、时间有重复的情况。 |
----provider | 对象 | 运输商信息节点。 |
-----key | 数值 | 运输商代码。 |
-----name | 字符串 | 运输商名称。 |
-----alias | 字符串 | 运输商别名。 |
-----tel | 字符串 | 运输商联系电话。 |
-----homepage | 字符串 | 运输商官网。 |
-----country | 字符串 | 运输商所属国家。 |
----service_type | 字符串 | 服务类型。 |
----latest_sync_status | 字符串 | 最近同步状态, Failure:同步失败; Success:同步成功; |
----latest_sync_time | 字符串 | 最近同步时间。 |
----events_hash | 数值 | 事件哈希值。 |
----provider_tips | 字符串 | 查询提示内容 |
----events | 数组 | 事件集合节点。 |
-----time_iso | 字符串 | 1. 事件发生时间(ISO 格式),由原始时间转换得到带时区的格式,原时间格式错误则显示原时间内容; 2. 上游运输商有时区信息则优先使用,没有按运输商总部所在的时区使用; 3. 例如:2022-03-02T20:43:24-06:00,表示当前为西6区; 4. 把(-06:00)时区信息去掉则为当地时间; |
-----time_utc | 字符串 | 1. 事件发生时间(UTC 时间),由 time_iso 转换得来,time_iso 无效则显示为 null。 2. 例如:2022-03-03T02:43:24Z; |
-----time_raw | 对象 | 运输商提供的原始时间信息, 1. 共三组分别是:年月日、时分秒、时区。 2. 如果是 null,则表示运输商没有提供数据。 |
------date | 字符串 | 年月日信息 |
------time | 字符串 | 时分秒信息 |
------timezone | 字符串 | 时区信息,如果 timezone 是 null,time_iso 是有效的时间则表示是由 17TRACK 补充的时区信息。 |
-----description | 字符串 | 事件描述,包括:事件发生的地点、运输中的行为、状态说明。 |
-----description_translation | 对象 | 描述翻译节点。 |
------description | 字符串 | 翻译后的事件描述。 |
------lang | 字符串 | 翻译语言代码 |
-----location | 字符串 | 地点。 |
-----stage | 字符串 | 里程碑状态,不保证一定会有状态信息,取决于上游运输商数据情况。 |
-----sub_status | 字符串 | 包裹子状态。 |
-----address | 对象 | 地点信息节点。 |
---------raw | 对象 | 原始信息 |
----------country | 字符串 | 国家地区。 |
----------state | 字符串 | 州、省。 |
----------city | 字符串 | 城市。 |
----------street | 字符串 | 街道。 |
----------postal_code | 字符串 | 邮编。 |
----------coordinates | 对象 | 位置坐标信息节点。 |
-----------longitude | 字符串 | 经度。 |
-----------latitude | 字符串 | 纬度。 |
------country | 字符串 | 国家地区。 |
------state | 字符串 | 州、省。 |
------city | 字符串 | 城市。 |
------street | 字符串 | 街道。 |
------postal_code | 字符串 | 邮编。 |
------coordinates | 对象 | 位置坐标信息节点。 |
-------longitude | 字符串 | 经度。 |
-------latitude | 字符串 | 纬度。 |
WebHook
操作流程
第一步 定义
开发一个接口,访问形式为 URL,用来接收API推送的物流信息(示例代码为 JAVA);
@RestController class WebhookController { WebhookController() { } @PostMapping("/notify") void notify(@RequestBody String body) { // body 是 接收到的推送内容 } }
第二步 设置
- 登录 API 账号并访问 https://api.17track.net/admin/settings ,点击左侧[设置],在右侧设置填入 第一步 的 URL 再点击[保存];
第三步 测试
- 在线验证是否畅通,点击左侧[WebHook 测试],在右侧填入待测试的 URL,点击[测试按钮]进行验证,若有 绿色 的“操作成功”提示弹出则为 URL 畅通。(可用 https://webhook.site 站点免费测试);
推送策略
- 推送由队列控制发送,建议您使用队列处理接收到的信息;
- 每次推送通知包含一个物流单号的全量信息;
- 接收推送的 Webhook URL 返回 HTTP状态码 200 表示被正常处理;
- HTTP状态码非 200 都判断为推送失败;
- 推送失败后会 重试 3 次,如果仍无法推送,将放弃推送此单号,等待下一次推送重试再进行。所有重试都失败,要等到下次自动跟踪再进行推送;
- 重试方式具体如下:
尝试次数 | 重试次数 | 重试间隔(秒) | 描述 |
---|---|---|---|
1 | 0 | 0 | 无。 |
2 | 1 | 600 | 第 10 分钟发起。 |
3 | 2 | 1800 | 第 30 分钟发起。 |
4 | 3 | 3600 | 第 1 个小时发起。 |
推送通知类型
停止跟踪通知
示例
{
"event": "TRACKING_STOPPED",
"data": {
"number": "RR123456789CN",
"carrier": 3011,
"param": null,
"tag": ""
}
}
响应结果说明:
名称 | 描述 |
---|---|
event | TRACKING_STOPPED,通知类型。 |
-number | 停止跟踪的物流单号。 |
-carrier | 停止跟踪的物流商。 |
更新跟踪通知
- 自动跟踪后若物流信息有变化,则会即刻触发推送,反之不会;
推送头信息示例
"content-type",
"content-length",
"sign":"9a44ab6... ...4b4bf5"
推送报文示例
{
"event": "TRACKING_UPDATED",
"data": {
"number": "RR123456789CN",
"carrier": 3011,
"param": "518000",
"tag": "myID",
"track_info": {
"shipping_info": {
"shipper_address": {
"country": "CN",
"state": "GD",
"city": "SHENZHEN",
"street": "HARTFORD CT DISTRIBUTION CENTER",
"postal_code": "518000",
"coordinates": {
"longitude": "114.085947",
"latitude": "22.547"
}
},
"recipient_address": {
"country": "AF",
"state": null,
"city": "KABUL",
"street": null,
"postal_code": null,
"coordinates": {
"longitude": null,
"latitude": null
}
}
},
"latest_status": {
"status": "InfoReceived",
"sub_status": "InfoReceived",
"sub_status_descr": null
},
"latest_event": {
"time_iso": "2022-03-02T20:43:24-06:00",
"time_utc": "2022-03-03T02:43:24Z",
"time_raw": {
"date": "2022-03-02",
"time": "20:43:24",
"timezone": "-06:00"
},
"description": "Shipment information sent to FedEx",
"description_translation": {
"lang": "en",
"description": "Shipment information sent to FedEx"
},
"location": "NJ",
"stage": "InfoReceived",
"sub_status": "InfoReceived",
"address": {
"country": "US",
"state": "NJ",
"city": "MARLTON",
"street": null,
"postal_code": "08053",
"coordinates": {
"longitude": null,
"latitude": null
}
}
},
"time_metrics": {
"days_after_order": 7,
"days_of_transit": 7,
"days_of_transit_done": 7,
"days_after_last_update": 57,
"estimated_delivery_date": {
"source":"Official",
"from": "2022-03-02T18:43:24-06:00",
"to": "2022-03-03T19:43:24-06:00"
}
},
"milestone": [
{
"key_stage": "InfoReceived",
"time_iso": "2023-08-14T00:00:00-05:00",
"time_utc": "2023-08-14T05:00:00Z",
"time_raw": {
"date": "2023-08-14",
"time": null,
"timezone": null
}
},
{
"key_stage": "PickedUp",
"time_iso": "2023-08-15T08:46:00-05:00",
"time_utc": "2023-08-15T12:46:00Z",
"time_raw": {
"date": "2023-08-15",
"time": "08:46:00",
"timezone": "-05:00"
}
},
{
"key_stage": "Departure",
"time_iso": null,
"time_utc": null,
"time_raw": {
"date": null,
"time": null,
"timezone": null
}
},
{
"key_stage": "Arrival",
"time_iso": null,
"time_utc": null,
"time_raw": {
"date": null,
"time": null,
"timezone": null
}
},
{
"key_stage": "AvailableForPickup",
"time_iso": null,
"time_utc": null,
"time_raw": {
"date": null,
"time": null,
"timezone": null
}
},
{
"key_stage": "OutForDelivery",
"time_iso": null,
"time_utc": null,
"time_raw": {
"date": null,
"time": null,
"timezone": null
}
},
{
"key_stage": "Delivered",
"time_iso": null,
"time_utc": null,
"time_raw": {
"date": null,
"time": null,
"timezone": null
}
},
{
"key_stage": "Returning",
"time_iso": null,
"time_utc": null,
"time_raw": {
"date": null,
"time": null,
"timezone": null
}
},
{
"key_stage": "Returned",
"time_iso": null,
"time_utc": null,
"time_raw": {
"date": null,
"time": null,
"timezone": null
}
}
],
"misc_info": {
"risk_factor": 0,
"service_type": "FedEx International Priority",
"weight_raw": "1.1 KG",
"weight_kg": "1.1",
"pieces": "1",
"dimensions": "22*20*16 CM",
"customer_number": "2459642000~270434455123~FX",
"reference_number": null,
"local_number": "270434455123",
"local_provider": "Fedex",
"local_key": 100003
},
"tracking": {
"providers_hash": 2067301750,
"providers": [
{
"provider": {
"key": 3011,
"name": "China Post",
"alias": "China Post",
"tel": null,
"homepage": "http://www.17track.net",
"country": "CN"
},
"service_type": "International Priority",
"latest_sync_status": "Success",
"latest_sync_time": "2022-06-09T05:46:31Z",
"events_hash": -227928244,
"events": [
{
"time_iso": "2023-08-14T00:00:00-05:00",
"time_utc": "2023-08-14T05:00:00Z",
"time_raw": {
"date": "2023-08-14",
"time": null,
"timezone": null
},
"description": "At local FedEx facility",
"description_translation": {
"lang": "en",
"description": "At local FedEx facility"
},
"location": "ANCHORAGE, AK, US",
"stage": "InfoReceived",
"sub_status": "InfoReceived",
"address": {
"country": "US",
"state": "AK",
"city": "ANCHORAGE",
"street": null,
"postal_code": "99502",
"coordinates": {
"longitude": "35.86166",
"latitude": "104.195397"
}
}
}
]
}
]
}
}
}
}
响应结果说明:
名称 |
类型 |
描述 |
---|---|---|
event | 字符串 | TRACKING_UPDATED,通知类型。 |
data | 对象 | 单号的跟踪详情,与 gettrackinfo接口 响应报文 accepted 结构一样。 |
-number | 字符串 | 物流单号。 |
-carrier | 数值 | 运输商代码。 |
-param | 字符串 | 物流单号附加参数,请参考【注册物流单号】入参说明 |
-tag | 字符串 | 自定义标签,最长 100 个字符。如:关联标识,备注分组等。 |
-track_info | 对象 | 物流信息主结构节点。 |
--shipping_info | 对象 | 地区相关信息节点。 |
---shipper_address | 对象 | 发件地信息节点。 |
----country | 字符串 | 国家或地区(大写)。 |
----state | 字符串 | 州、省。 |
----postal_code | 字符串 | 邮编。 |
----city | 字符串 | 城市。 |
----street | 字符串 | 街道。 |
----coordinates | 对象 | 位置坐标(如经度纬度)。 |
-----longitude | 字符串 | 经度。 |
-----latitude | 字符串 | 纬度。 |
---recipient_address | 对象 | 收件地信息节点。 |
----country | 字符串 | 国家或地区(大写)。 |
----state | 字符串 | 州、省。 |
----postal_code | 字符串 | 邮编。 |
----city | 字符串 | 城市。 |
----street | 字符串 | 街道。 |
----coordinates | 对象 | 位置坐标(如经度纬度)。 |
-----longitude | 字符串 | 经度。 |
-----latitude | 字符串 | 纬度。 |
--latest_status | 对象 | 最新状态节点。 |
---status | 字符串 | 物流主状态。 |
---sub_status | 字符串 | 包裹子状态。 |
---sub_status_descr | 字符串 | 状态描述。 |
--latest_event | 对象 | 最新事件,信息结构与描述参考 events 集合。 |
--time_metrics | 对象 | 时效相关信息节点,其中 estimated_delivery_date 为时间区间。 |
---days_after_order | 数值 | 运单时效: 签收状态时,间隔天数 = 签收时间 - 第 1 条事件时间 非签收状态且有结果时,间隔天数 = 当前时间 - 第 1 条事件时间 无结果时,间隔天数 = 0 |
---days_after_last_update | 数值 | 信息无更新天数: 签收、退件签收、无结果时,间隔天数 = 0 其它情况时,间隔天数 = 当前时间 - 最后 1 条事件时间 |
---days_of_transit | 数值 | 运输时效: 为签收状态时: 1. 有 InTransit_PickedUp,间隔时间 = 签收时间 - 揽收时间 2. 无 InTransit_PickedUp,有 InfoReceived,间隔时间 = 签收时间 - InfoReceived 后首个事件时间 3. InTransit_PickedUp 和 InfoReceived 都没有,间隔时间 = 签收时间 - 第 1 条事件时间 非签收状态且有轨迹跟踪结果时: 1. 有 InTransit_PickedUp,间隔时间=当前时间 - 揽收时间 2.无 InTransit_PickedUp,有 InfoReceived,间隔时间 = 当前时间 - InfoReceived 后首个事件时间 3. 无 InTransit_PickedUp,有 InfoReceived,但只有 1 条轨迹时,间隔时间 = 0 4. InTransit_PickedUp 和 InfoReceived 都没有, 间隔时间 = 当前时间 - 第 1 条事件时间 无轨迹跟踪结果时:间隔天数 = 0 |
---days_of_transit_done | 数值 | 妥投时效: 为签收状态时: 1. 有 InTransit_PickedUp,间隔时间 = 签收时间 - 揽收时间 2. 无 InTransit_PickedUp,有 InfoReceived,间隔时间 = 签收时间 - InfoReceived 后首个事件时间 3. InTransit_PickedUp 和 InfoReceived 都没有,间隔时间 = 签收时间 - 第 1 条事件时间 非签收状态时:间隔天数 = 0 |
---estimated_delivery_date | 对象 | 预期达到时间信息节点。 |
----source | 字符串 | 表示 from 和 to 的内容提供者,17TRACK 表示 17TRACK 提供,Official 表示由运输商官方提供,null 表示没有提供者。 |
----from | 字符串 | 预计投递最早时间(ISO 格式),例如:2021-09-01T08:00:54-05:00。 |
----to | 字符串 | 预计投递最晚时间(ISO 格式),例如:2021-09-01T08:00:54-05:00。 |
---milestone | 数组 | 里程碑 作用:展示承运过程中的主要节点及发生时间 用法:遍历 milestone 各项,建议顺序为:InfoReceived >> PickedUp >> Departure >> Arrival >> OutForDelivery >> Delivered。 (AvailableForPickup、Returned、Returning 按具体情况使用) 注意:如果 time_iso 或 time_utc 为 null,则表示运输商未提供事件描述。可以用 milestone[].key_stage 在 tracking.providers[].events[].stage 中查询比较具体事件内容。 milestone 的 key_stage 含义: InfoReceived:收到信息,运输商收到商家的下单信息,等待上门取件。 PickedUp:揽收,运输商收取商家的包裹。 Departure:离港,离开发件国港口(理论上是清关后的动作)。 Arrival:到港,到达收件国港口(是否有清关并不确定)。 AvailableForPickup:到达待取,包裹已经到达目的地的投递点,需要收件人自取。 OutForDelivery:派送途中,包裹正在投递过程中。 Delivered:成功签收,包裹已妥投。 Returned:退件,包裹已经完成退件操作。 Returning:退件中,包裹在处理,但不保证处理完会转成"退件"状态。 |
---key_stage | 字符串 | 里程碑状态,不保证一定会有状态信息,取决于上游运输商数据情况。 |
---time_iso | 字符串 | 1. 状态发生的时间(ISO 格式),由运输商当地时间转换得出带时区的格式,当时间格式错误则显示原始时间; 2. 上游运输商有时区信息则优先使用,没有按运输商总部所在的时区使用; 3. 例如:2022-03-02T20:43:24-06:00,表示当前为西6区; 4. 把(-06:00)时区信息去掉则为运输商当地时间; 5. 此值对应事件集合中的 time_iso,即: tracking.providers[].provider[].events[].time_iso; |
---time_utc | 字符串 | 1. 状态发生的时间(UTC 格式),由 time_iso 转换得来,time_iso 无效则显示为 null。 2. 例如:2022-03-03T02:43:24Z; 3. 此值对应事件集合中的 time_utc,即: tracking.providers[].provider[].events[].time_utc; |
---time_raw | 对象 | 运输商提供的原始时间信息, 1. 共三组分别是:年月日、时分秒、时区。 2. 如果是 null,则表示运输商没有提供数据。 |
----date | 字符串 | 年月日信息 |
----time | 字符串 | 时分秒信息 |
----timezone | 字符串 | 时区信息,如果 timezone 是 null,time_iso 是有效的时间则表示是由 17TRACK 补充的时区信息。 |
--misc_info | 对象 | 包裹附属信息节点。 |
---risk_factor | 字符串 | 包裹风险系数。 |
---service_type | 字符串 | 服务类型。 |
---weight_raw | 字符串 | 原始重量信息,返回的重量单位根据运输商提供,有可能是克、公斤、磅等。 |
---weight_kg | 字符串 | 把原始重量信息( weight_raw) 转换为公斤。 |
---pieces | 字符串 | 件数。 |
---dimensions | 字符串 | 原始体积尺寸(长宽高),不同运输商可能会存在不同的类型,目前大多数运输商使用的是cm单位。 |
---customer_number | 字符串 | 收货客户单号。 |
---reference_number | 字符串 | 参考号。 |
---local_number | 字符串 | 尾程单号。 |
---local_provider | 字符串 | 尾程运输商。 |
---local_key | 数值 | 尾程运输商代码。 |
--tracking | 对象 | 物流信息节点。 |
---providers_hash | 数值 | 哈希值,根据事件内容计算出来,用于判断是否有变更。 |
---providers | 数组 | 运输商集合节点 特别情况说明:当前包裹是邮政承运时,providers[0] 对象表示目的地运输商信息,providers[1] 对象表示发件地运输商信息,有可能会出现 providers[0] 和 providers[1] 的轨迹描述、时间有重复的情况。 |
----provider | 对象 | 运输商信息节点。 |
-----key | 数值 | 运输商代码。 |
-----name | 字符串 | 运输商名称。 |
-----alias | 字符串 | 运输商别名。 |
-----tel | 字符串 | 运输商联系电话。 |
-----homepage | 字符串 | 运输商官网。 |
-----country | 字符串 | 运输商所属国家。 |
----service_type | 字符串 | 服务类型。 |
----latest_sync_status | 字符串 | 最近同步状态, Failure:同步失败; Success:同步成功; |
----latest_sync_time | 字符串 | 最近同步时间。 |
----events_hash | 数值 | 事件哈希值。 |
----events | 数组 | 事件集合节点。 |
-----time_iso | 字符串 | 1. 事件发生时间(ISO 格式),由原始时间转换得到带时区的格式,原时间格式错误则显示原时间内容; 2. 上游运输商有时区信息则优先使用,没有按运输商总部所在的时区使用; 3. 例如:2022-03-02T20:43:24-06:00,表示当前为西6区; 4. 把(-06:00)时区信息去掉则为当地时间; |
-----time_utc | 字符串 | 1. 事件发生时间(UTC 时间),由 time_iso 转换得来,time_iso 无效则显示为 null。 2. 例如:2022-03-03T02:43:24Z; |
-----time_raw | 对象 | 运输商提供的原始时间信息, 1. 共三组分别是:年月日、时分秒、时区。 2. 如果是 null,则表示运输商没有提供数据。 |
------date | 字符串 | 年月日信息 |
------time | 字符串 | 时分秒信息 |
------timezone | 字符串 | 时区信息,如果 timezone 是 null,time_iso 是有效的时间则表示是由 17TRACK 补充的时区信息。 |
-----description | 字符串 | 事件描述,包括:事件发生的地点、运输中的行为、状态说明。 |
-----description_translation | 对象 | 描述翻译节点。 |
------description | 字符串 | 翻译后的事件描述。 |
------lang | 字符串 | 翻译语言代码 |
-----location | 字符串 | 地点。 |
-----stage | 字符串 | 里程碑状态,不保证一定会有状态信息,取决于上游运输商数据情况。 |
-----sub_status | 字符串 | 包裹子状态。 |
-----address | 对象 | 地点信息节点。 |
------country | 字符串 | 国家地区。 |
------state | 字符串 | 州、省。 |
------city | 字符串 | 城市。 |
------street | 字符串 | 街道。 |
------postal_code | 字符串 | 邮编。 |
------coordinates | 对象 | 位置坐标信息节点。 |
-------longitude | 字符串 | 经度。 |
-------latitude | 字符串 | 纬度。 |
验证签名流程
- 每次推送通知都会携带签名信息,为确保来源是 17TRACK,建议先验证签名再使用;
- 签名信息放在推送的请求头 sign 属性中;
- 生成签名的基础信息要取原始 更新跟踪通知 报文,不能对其做任何修改再使用;
第一步 拼接待生成签名内容
原始 更新跟踪通知 的报文 + / + 密钥 比如:
- 更新跟踪通知报文是
{"event":"TRACKING_UPDATED","data":{"number":"RR123456789CN", "carrier":3011,"tag":null}}
- 密钥是
123456ABCDEF
- 待生成签名内容是
{"event":"TRACKING_UPDATED","data":{"number":"RR123456789CN","carrier":3011,"tag":null}}/123456ABCDEF
第二步 SHA256编码
使用 SHA256 十六进制编码生成签名结果(生成签名示例代码为 JAVA);
/**
* requestText {String} 原始通知报文
* key {String} 密钥
* return {String} 生成签名内容
*/
private String getGeneratedSignature(String requestText, String key) throws NoSuchAlgorithmException {
String src = requestText + "/" + key;
MessageDigest md = MessageDigest.getInstance("SHA-256");
byte[] hash = md.digest(src.getBytes(StandardCharsets.UTF_8));
BigInteger number = new BigInteger(1, hash);
StringBuilder hexString = new StringBuilder(number.toString(16));
while (hexString.length() < 64) {
hexString.insert(0, '0');
}
return hexString.toString();
}
第三步 比较结果
生成签名结果与 sign 一致则验证通过,即推送通知来源是 17TRACK;