API
与网站相同的数据和计算,以只读 JSON 接口提供。每个工具都由与其页面相同的代码计算,所以这里的结果就是页面上的结果;数据集也是网站展示的那些,附带版本和来源。
适合围绕出口报价、货运体积和退税自己做工具或核对的人,以及需要这些数字却不想抓取网页的程序。这里不写入任何东西:你发送输入,得到结果。
接口地址https://chukoudan.com/v1/
接口列表
所有接口都在 /v1/ 下,都返回 JSON。
| 方法 | 地址 | 说明 | 可选参数 |
|---|---|---|---|
| GET | /v1/datasets | 本站可展示的数据集,每个附当前版本。 | ?lang |
| GET | /v1/datasets/{id} | 一个数据集及其全部版本,新的在前。 | ?lang |
| GET | /v1/datasets/{id}/current | 当前版本的数据行,分页返回。 | ?offset ?limit ?lang |
| GET | /v1/datasets/{id}/{version} | 某个版本的数据行,分页返回;已发布的版本永不改动。 | ?offset ?limit ?lang |
| GET | /v1/tools | 全部计算器:编号、名称和各自读取的数据。 | ?lang |
| GET | /v1/tools/{id} | 一个计算器:名称、输入项和读取的数据集。 | ?lang |
| POST | /v1/tools/{id}/compute | 用你给的输入运行一个计算器,结果与本站页面给出的一致。输入以 JSON 放在请求正文里。 | ?lang |
| GET | /v1/openapi.json | 本 API 的 OpenAPI 3.1 文档。 | – |
无需密钥,无需账号
不用注册,直接请求即可。接口不设 Cookie,也不保存你发给计算的输入。限制是按请求方设置的,而不是用密钥。
请求限制
每个请求方可连续发出最多 60 次请求,之后按每分钟 60 次补充。请求方按 IP 地址区分(IPv6 按其 /64 网段)。每个响应的头里都写明你的余量:RateLimit-Limit 是满桶的大小,RateLimit-Remaining 是剩余次数,RateLimit-Reset 是桶重新装满还要多少秒。用完后返回 429,并带 Retry-After 头:再次请求前需要等待的秒数。
一页数据行按每 1000 行算一次请求。一次最多取 5000 行(limit),offset 用来跳过行。计算请求的正文最多 256 KB,且必须是 JSON。
一个桶里只有 1 次额度的请求方,发出第二次请求时得到的响应:
curl 'https://chukoudan.com/v1/tools'
HTTP 429
access-control-allow-origin: *
cache-control: no-store
content-type: application/json
ratelimit-limit: 1
ratelimit-remaining: 0
ratelimit-reset: 60
retry-after: 60
{
"issues": [
{
"path": "",
"code": "api.rate_limited",
"values": {}
}
],
"provenance": {
"api": "v1",
"site": "chukoudan.com",
"generated_at": "2026-10-07T04:00:00.000Z",
"language": "zh-CN",
"datasets": [],
"license": {
"status": "draft",
"ours": "dataset.license.ours",
"underlying": "dataset.license.underlying"
}
}
}缓存
可以保存的响应带有 ETag 和 Cache-Control:数据集列表、数据集的版本列表和当前版本的数据行可保存 1 分钟,工具说明 5 分钟,不是当前版本的数据行 1 天。请求时带上 If-None-Match,内容没有变化就得到 304 和空正文,304 仍计入请求限制。出错的响应和所有计算结果都不保存(no-store)。
从浏览器调用
任何网站都可以在访客的浏览器里调用这些接口(GET 和 POST,不带凭据)。计算只接受 JSON:其他内容类型会被拒绝,返回 415。
响应的样子
一次计算返回 tool(工具编号)、outputs(按名称列出的各个数字)、steps(逐行的计算过程)、warnings 和 provenance。输入不合格时返回 400 和 issues,而不是 outputs。响应里没有句子:steps、warnings 和 issues 只带文案键(如 cbm.more_than_20gp)和用来填入的数值,文字由你用自己的语言来写。
数字的写法
每个数字都带类型标记,告诉你该怎么写,数值一律是精确的十进制字符串,绝不是浮点数。quantity 有 value、unit,有时还有 places(保留的小数位数:补零到这个位数,不要再四舍五入);money 有 amount 和 currency;ratio 是小数形式的比例(0.13 即 13%);rate 表示 per 个 base 兑 value 个 quote;另有 count、code(来自固定清单的标记)和 date。
数字从哪里来
每个响应(包括错误)都带 provenance:api(版本,v1)、site、generated_at、language,以及 datasets(这次回答用到的每个数据集版本,含 published_at 日期、origin 和可以引用的来源说明)和 license。在任何请求上加 lang=zh-CN、en、ja 或 ko,可选择来源说明的语言,其他内容不变。license 目前是草案,在文本获得批准之前,里面是文案键而不是文字。
错误
错误响应有 issues(每项含 path、code、values)和 provenance。400:输入被拒绝(path 指出是哪个字段,code 说明原因,code 是文案键);404:没有这个工具、数据集或版本;413:正文过大;415:不是 JSON;429:超过限制;500:我们这边出了问题,响应不会说明更多原因。
一次计算
把工具的输入 POST 到 /v1/tools/ID/compute。下面的例子算的是:450 箱,每箱 60 × 40 × 50 cm、18 kg,走拼箱(LCL)的立方米数。在 CBM 页面输入同样的数据,得到的是同样的数字。
请求
curl -X POST 'https://chukoudan.com/v1/tools/cbm/compute' -H 'content-type: application/json' -d '{"inputs":{"cartons":[{"length":"60","width":"40","height":"50","grossWeight":"18","quantity":"450"}],"lengthUnit":"cm","weightUnit":"kg","mode":"lcl"}}'响应
HTTP 200
access-control-allow-origin: *
cache-control: no-store
content-type: application/json
ratelimit-limit: 60
ratelimit-remaining: 59
ratelimit-reset: 1
{
"tool": "cbm",
"outputs": {
"totalVolume": {
"kind": "quantity",
"value": "54",
"unit": "m3"
},
"totalGrossWeight": {
"kind": "quantity",
"value": "8100",
"unit": "kg"
},
"perCartonVolume": {
"kind": "quantity",
"value": "0.12",
"unit": "m3"
},
"airVolumetric": {
"kind": "quantity",
"value": "9000",
"unit": "kg"
},
"airChargeable": {
"kind": "quantity",
"value": "9000",
"unit": "kg"
},
"airBy": {
"kind": "code",
"value": "volume"
},
"expressVolumetric": {
"kind": "quantity",
"value": "10800",
"unit": "kg"
},
"expressChargeable": {
"kind": "quantity",
"value": "10800",
"unit": "kg"
},
"expressBy": {
"kind": "code",
"value": "volume"
},
"lclChargeable": {
"kind": "quantity",
"value": "54",
"unit": "m3"
},
"lclBy": {
"kind": "code",
"value": "volume"
},
"chargeable": {
"kind": "quantity",
"value": "54",
"unit": "m3"
}
},
"steps": [
{
"id": "cbm.row",
"values": {
"row": {
"kind": "count",
"value": "1"
},
"length": {
"kind": "quantity",
"value": "60",
"unit": "cm"
},
"width": {
"kind": "quantity",
"value": "40",
"unit": "cm"
},
"height": {
"kind": "quantity",
"value": "50",
"unit": "cm"
},
"grossWeight": {
"kind": "quantity",
"value": "18",
"unit": "kg"
},
"quantity": {
"kind": "count",
"value": "450"
},
"cartonVolume": {
"kind": "quantity",
"value": "120000",
"unit": "cm3"
},
"perCartonVolume": {
"kind": "quantity",
"value": "0.12",
"unit": "m3"
},
"volume": {
"kind": "quantity",
"value": "54",
"unit": "m3"
},
"weight": {
"kind": "quantity",
"value": "8100",
"unit": "kg"
},
"airVolumetric": {
"kind": "quantity",
"value": "9000",
"unit": "kg"
},
"airDivisor": {
"kind": "count",
"value": "6000",
"grouping": false
},
"expressVolumetric": {
"kind": "quantity",
"value": "10800",
"unit": "kg"
},
"expressDivisor": {
"kind": "count",
"value": "5000",
"grouping": false
}
}
},
{
"id": "cbm.total",
"values": {
"totalVolume": {
"kind": "quantity",
"value": "54",
"unit": "m3"
},
"totalGrossWeight": {
"kind": "quantity",
"value": "8100",
"unit": "kg"
}
}
},
{
"id": "cbm.lcl",
"values": {
"volume": {
"kind": "quantity",
"value": "54",
"unit": "m3"
},
"weight": {
"kind": "quantity",
"value": "8.1",
"unit": "t",
"places": 3
},
"chargeable": {
"kind": "quantity",
"value": "54",
"unit": "m3"
},
"by": {
"kind": "code",
"value": "volume"
}
}
},
{
"id": "cbm.air",
"values": {
"volumetric": {
"kind": "quantity",
"value": "9000",
"unit": "kg"
},
"weight": {
"kind": "quantity",
"value": "8100",
"unit": "kg"
},
"chargeable": {
"kind": "quantity",
"value": "9000",
"unit": "kg"
},
"by": {
"kind": "code",
"value": "volume"
}
}
},
{
"id": "cbm.express",
"values": {
"volumetric": {
"kind": "quantity",
"value": "10800",
"unit": "kg"
},
"weight": {
"kind": "quantity",
"value": "8100",
"unit": "kg"
},
"chargeable": {
"kind": "quantity",
"value": "10800",
"unit": "kg"
},
"by": {
"kind": "code",
"value": "volume"
}
}
}
],
"warnings": [
{
"code": "cbm.more_than_20gp",
"values": {
"totalVolume": {
"kind": "quantity",
"value": "54",
"unit": "m3"
},
"gp20Volume": {
"kind": "quantity",
"value": "33.115",
"unit": "m3"
}
},
"level": "hint",
"next": "zhuanggui"
}
],
"provenance": {
"api": "v1",
"site": "chukoudan.com",
"generated_at": "2026-10-07T04:00:00.000Z",
"language": "zh-CN",
"datasets": [
{
"id": "divisors",
"version": "2026-09-24-2",
"published_at": "2026-09-24",
"origin": "chukoudan-divisors",
"source": "体积重系数:常用系数(2026-09-24 整理),以承运商为准"
},
{
"id": "containers",
"version": "2026-09-24-2",
"published_at": "2026-09-24",
"origin": "chukoudan-container-reference",
"source": "柜型尺寸和最大载重:常用参考值(2026-09-24 整理),以承运商为准"
}
],
"license": {
"status": "draft",
"ours": "dataset.license.ours",
"underlying": "dataset.license.underlying"
}
}
}warnings 里有一条 hint(cbm.more_than_20gp):54 m³ 装不进一个 20GP,next 是可以接着用的工具的页面标识。
一个数据集
GET /v1/datasets 列出网站展示的数据集;/v1/datasets/ID 列出某个数据集的各个版本;/v1/datasets/ID/current 返回当前版本的数据行;/v1/datasets/ID/VERSION 返回指定版本,已发布的版本永不改变。每个版本有 content_hash,可以用来判断你手上的是不是同一份。数据集的响应里都带有 CSV 和 JSON 下载的链接。
请求
curl 'https://chukoudan.com/v1/datasets/ports/current?limit=2&lang=en'响应
HTTP 200
access-control-allow-origin: *
cache-control: public, max-age=60
content-type: application/json
etag: W/"5e81138d2bd087290f4dbc776003b1cf"
ratelimit-limit: 60
ratelimit-remaining: 59
ratelimit-reset: 1
{
"dataset": "ports",
"version": "2026-09-25",
"published_at": "2026-09-25",
"fetched_at": "2026-09-24T19:59:07Z",
"content_hash": "sha256:a222c1be3c0bd7146efc3a2b6a5f9ac0d246edfd4570b6075cfd6b0494eb37af",
"rows": 38,
"columns": [
"id",
"name.zh-CN",
"name.en",
"name.ja",
"name.ko",
"region",
"search.zh",
"search.pinyin",
"search.en"
],
"current": true,
"links": {
"self": "/v1/datasets/ports/2026-09-25",
"csv": "/data/ports/2026-09-25.csv",
"json": "/data/ports/2026-09-25.json"
},
"license": {
"ours": "dataset.license.ours",
"underlying": "dataset.license.underlying.free",
"draft": true
},
"offset": 0,
"limit": 2,
"next": 2,
"data": [
{
"id": "shanghai",
"name": {
"zh-CN": "上海",
"en": "Shanghai",
"ja": "上海",
"ko": "상하이"
},
"region": "上海",
"search": {
"zh": [
"上海港",
"洋山"
],
"pinyin": [
"sh",
"shg"
],
"en": [
"Yangshan"
]
}
},
{
"id": "ningbo",
"name": {
"zh-CN": "宁波",
"en": "Ningbo",
"ja": "寧波",
"ko": "닝보"
},
"region": "浙江",
"search": {
"zh": [
"宁波舟山",
"北仑",
"舟山"
],
"pinyin": [
"nb",
"nbzs"
],
"en": [
"Ningbo-Zhoushan",
"Beilun"
]
}
}
],
"provenance": {
"api": "v1",
"site": "chukoudan.com",
"generated_at": "2026-10-07T04:00:00.000Z",
"language": "en",
"datasets": [
{
"id": "ports",
"version": "2026-09-25",
"published_at": "2026-09-25",
"origin": "chukoudan-port-list",
"source": null
}
],
"license": {
"status": "draft",
"ours": "dataset.license.ours",
"underlying": "dataset.license.underlying"
}
}
}数据行里的数字保持发布时的字符串原样。翻页用 offset 和 limit;最后一页的 next 是 null。
示例是用本站接口自己的代码在 2026-10-07 实际运行得到的,没有改动。
完整说明
GET /v1/openapi.json 是机器可读的说明(OpenAPI 3.1),涵盖每个路径、响应和每个工具的输入;它由工具本身生成,所以不会与接口的实际行为不一致。下面各工具的输入表就来自它。
计算器及其输入项
每个计算器的地址是 /v1/tools/ 加它的编号,再加 /compute。下面列出每个计算器的输入项、返回的数值和读取的数据。
FOB/CIF/CFR 报价baojia
由成本算三种术语报价和利润
- 地址
POST /v1/tools/baojia/compute- 计算器页面
- FOB/CIF/CFR 报价
- 读取的数据
central-parity@current, ports@current, refund-rates@current- 返回的数值
priceFob, totalFob, commissionPriceFob*, commissionTotalFob*, profitFob, marginFob*, marginAltFob*, breakEvenFob, priceCfr*, totalCfr*, commissionPriceCfr*, commissionTotalCfr*, profitCfr*, marginCfr*, marginAltCfr*, breakEvenCfr*, priceCif*, totalCif*, commissionPriceCif*, commissionTotalCif*, profitCif*, marginCif*, marginAltCif*, breakEvenCif*, refundTotal, costTotal* (不一定出现)
| 输入项 | 类型 | 是否必填 |
|---|---|---|
mode | choice | 选填 |
price | decimal | 必填 |
quantity | decimal | 必填 |
unit | choice | 选填 |
taxRate | decimal | 必填 |
refundRate | decimal | 必填 |
domestic | decimal | 选填 |
domesticBasis | choice | 选填 |
currency | currency | 选填 |
fxRate | decimal | 必填 |
fxPer | choice | 选填 |
freight | decimal | 选填 |
freightBasis | choice | 选填 |
containers | integer | 选填 |
volume | decimal | 选填 |
insuranceRate | decimal | 选填 |
markup | decimal | 选填 |
commission | decimal | 选填 |
margin | decimal | 选填 |
marginBasis | choice | 选填 |
term | choice | 选填 |
quotedPrice | decimal | 选填 |
port | text | 选填 |
CBM / 体积重cbm
算立方数、毛重和空运快递计费重
- 地址
POST /v1/tools/cbm/compute- 计算器页面
- CBM / 体积重
- 读取的数据
divisors@current, containers@current- 返回的数值
totalVolume, lclChargeable, perCartonVolume*, totalGrossWeight, airChargeable, expressChargeable, airVolumetric, expressVolumetric, chargeable, airBy, expressBy, lclBy* (不一定出现)
| 输入项 | 类型 | 是否必填 |
|---|---|---|
cartons | rows | 必填 |
lengthUnit | choice | 选填 |
weightUnit | choice | 选填 |
mode | choice | 选填 |
airDivisor | integer | 选填 |
expressDivisor | integer | 选填 |
装柜计算器container-load
每柜装多少箱、要几个柜、怎么摆
- 地址
POST /v1/tools/container-load/compute- 计算器页面
- 装柜计算器
- 读取的数据
containers@current- 返回的数值
perContainer20GP*, containers20GP*, lastContainer20GP*, rows20GP*, columns20GP*, layers20GP*, along20GP*, across20GP*, up20GP*, volumeUse20GP*, weightUse20GP*, limit20GP*, rank20GP*, spareLength20GP*, spareWidth20GP*, spareHeight20GP*, spareLengthIn20GP*, spareWidthIn20GP*, spareHeightIn20GP*, perContainer40GP*, containers40GP*, lastContainer40GP*, rows40GP*, columns40GP*, layers40GP*, along40GP*, across40GP*, up40GP*, volumeUse40GP*, weightUse40GP*, limit40GP*, rank40GP*, spareLength40GP*, spareWidth40GP*, spareHeight40GP*, spareLengthIn40GP*, spareWidthIn40GP*, spareHeightIn40GP*, perContainer40HQ*, containers40HQ*, lastContainer40HQ*, rows40HQ*, columns40HQ*, layers40HQ*, along40HQ*, across40HQ*, up40HQ*, volumeUse40HQ*, weightUse40HQ*, limit40HQ*, rank40HQ*, spareLength40HQ*, spareWidth40HQ*, spareHeight40HQ*, spareLengthIn40HQ*, spareWidthIn40HQ*, spareHeightIn40HQ*, perContainer45HQ*, containers45HQ*, lastContainer45HQ*, rows45HQ*, columns45HQ*, layers45HQ*, along45HQ*, across45HQ*, up45HQ*, volumeUse45HQ*, weightUse45HQ*, limit45HQ*, rank45HQ*, spareLength45HQ*, spareWidth45HQ*, spareHeight45HQ*, spareLengthIn45HQ*, spareWidthIn45HQ*, spareHeightIn45HQ*, best** (不一定出现)
| 输入项 | 类型 | 是否必填 |
|---|---|---|
lengthUnit | choice | 选填 |
weightUnit | choice | 选填 |
length | decimal | 必填 |
width | decimal | 必填 |
height | decimal | 必填 |
grossWeight | decimal | 必填 |
quantity | integer | 选填 |
fill | boolean | 选填 |
upright | boolean | 选填 |
maxLayers | integer | 选填 |
containerType | choice | 选填 |
单位换算unit-convert
长度、重量、体积,按国际通用的定义系数换算
- 地址
POST /v1/tools/unit-convert/compute- 计算器页面
- 单位换算
- 读取的数据
- 不读数据,汇率等放在输入里
- 返回的数值
result
| 输入项 | 类型 | 是否必填 |
|---|---|---|
value | decimal | 必填 |
from | choice | 必填 |
to | choice | 必填 |
出口退税计算器tuishui
填发票金额和退税率,立刻看到应退税额和每一步的出处
- 地址
POST /v1/tools/tuishui/compute- 计算器页面
- 出口退税计算器
- 读取的数据
refund-rates@current, central-parity@current- 返回的数值
refund*, basis*, inputVat*, costAddition*, nonCreditableOffset*, nonCreditable*, taxPayable*, endCredit*, exemptionOffset*, exemption*, exempted*, carriedForward*, taxDue** (不一定出现)
| 输入项 | 类型 | 是否必填 |
|---|---|---|
enterpriseType | choice | 必填 |
mode | choice | 选填 |
exports | rows | 必填 |
outputTax | decimal | 选填 |
inputTax | decimal | 选填 |
carriedCredit | decimal | 选填 |
declaredEndCredit | decimal | 选填 |
结算汇率fx-convert
人民币汇率中间价,和按你的银行价估算的结汇金额
- 地址
POST /v1/tools/fx-convert/compute- 计算器页面
- 结算汇率
- 读取的数据
central-parity@current- 返回的数值
midpoint, bankRate*, gap*, gapShown*, estimated*, atMidpoint*, atBank*, difference** (不一定出现)
| 输入项 | 类型 | 是否必填 |
|---|---|---|
currency | currency | 必填 |
amount | decimal | 选填 |
bankRate | decimal | 选填 |
keptRate | decimal | 选填 |
keptMidpoint | decimal | 选填 |
keptOn | text | 选填 |
结汇成本计算器fx-cost
比较银行和其他方式一年到手多少人民币
- 地址
POST /v1/tools/fx-cost/compute- 计算器页面
- 结汇成本计算器
- 读取的数据
central-parity@current- 返回的数值
annualBank, feesBank, costBank, gainBank, rankBank, annualB*, feesB*, costB*, gainB*, rankB*, annualC*, feesC*, costC*, gainC*, rankC*, annualMidpoint, best* (不一定出现)
| 输入项 | 类型 | 是否必填 |
|---|---|---|
receipts | rows | 必填 |
bankFee | decimal | 选填 |
useB | boolean | 选填 |
nameB | text | 选填 |
feePercentB | decimal | 选填 |
feePerReceiptB | decimal | 选填 |
useC | boolean | 选填 |
nameC | text | 选填 |
feePercentC | decimal | 选填 |
feePerReceiptC | decimal | 选填 |
唛头生成maitou
正唛和侧唛,A4 或 100×150 mm 标签直接打印
- 地址
POST /v1/tools/maitou/compute- 计算器页面
- 唛头生成
- 读取的数据
- 不读数据,汇率等放在输入里
- 返回的数值
- –
| 输入项 | 类型 | 是否必填 |
|---|---|---|
cartons | integer | 必填 |
length | decimal | 必填 |
width | decimal | 必填 |
height | decimal | 必填 |
grossWeight | decimal | 必填 |
netWeight | decimal | 必填 |
lines | rows | 选填 |
capitals | boolean | 选填 |
想要文件而不是接口?每个数据集都有可引用的网页,并提供 CSV 和 JSON 下载:数据来源与许可