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/openapi.json

计算器及其输入项

每个计算器的地址是 /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 * (不一定出现)
输入项类型是否必填
modechoice选填
pricedecimal必填
quantitydecimal必填
unitchoice选填
taxRatedecimal必填
refundRatedecimal必填
domesticdecimal选填
domesticBasischoice选填
currencycurrency选填
fxRatedecimal必填
fxPerchoice选填
freightdecimal选填
freightBasischoice选填
containersinteger选填
volumedecimal选填
insuranceRatedecimal选填
markupdecimal选填
commissiondecimal选填
margindecimal选填
marginBasischoice选填
termchoice选填
quotedPricedecimal选填
porttext选填
CBM / 体积重cbm

算立方数、毛重和空运快递计费重

地址
POST /v1/tools/cbm/compute
计算器页面
CBM / 体积重
读取的数据
divisors@current, containers@current
返回的数值
totalVolume, lclChargeable, perCartonVolume*, totalGrossWeight, airChargeable, expressChargeable, airVolumetric, expressVolumetric, chargeable, airBy, expressBy, lclBy * (不一定出现)
输入项类型是否必填
cartonsrows必填
lengthUnitchoice选填
weightUnitchoice选填
modechoice选填
airDivisorinteger选填
expressDivisorinteger选填
装柜计算器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* * (不一定出现)
输入项类型是否必填
lengthUnitchoice选填
weightUnitchoice选填
lengthdecimal必填
widthdecimal必填
heightdecimal必填
grossWeightdecimal必填
quantityinteger选填
fillboolean选填
uprightboolean选填
maxLayersinteger选填
containerTypechoice选填
单位换算unit-convert

长度、重量、体积,按国际通用的定义系数换算

地址
POST /v1/tools/unit-convert/compute
计算器页面
单位换算
读取的数据
不读数据,汇率等放在输入里
返回的数值
result
输入项类型是否必填
valuedecimal必填
fromchoice必填
tochoice必填
出口退税计算器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* * (不一定出现)
输入项类型是否必填
enterpriseTypechoice必填
modechoice选填
exportsrows必填
outputTaxdecimal选填
inputTaxdecimal选填
carriedCreditdecimal选填
declaredEndCreditdecimal选填
结算汇率fx-convert

人民币汇率中间价,和按你的银行价估算的结汇金额

地址
POST /v1/tools/fx-convert/compute
计算器页面
结算汇率
读取的数据
central-parity@current
返回的数值
midpoint, bankRate*, gap*, gapShown*, estimated*, atMidpoint*, atBank*, difference* * (不一定出现)
输入项类型是否必填
currencycurrency必填
amountdecimal选填
bankRatedecimal选填
keptRatedecimal选填
keptMidpointdecimal选填
keptOntext选填
结汇成本计算器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 * (不一定出现)
输入项类型是否必填
receiptsrows必填
bankFeedecimal选填
useBboolean选填
nameBtext选填
feePercentBdecimal选填
feePerReceiptBdecimal选填
useCboolean选填
nameCtext选填
feePercentCdecimal选填
feePerReceiptCdecimal选填
唛头生成maitou

正唛和侧唛,A4 或 100×150 mm 标签直接打印

地址
POST /v1/tools/maitou/compute
计算器页面
唛头生成
读取的数据
不读数据,汇率等放在输入里
返回的数值
–
输入项类型是否必填
cartonsinteger必填
lengthdecimal必填
widthdecimal必填
heightdecimal必填
grossWeightdecimal必填
netWeightdecimal必填
linesrows选填
capitalsboolean选填

想要文件而不是接口?每个数据集都有可引用的网页,并提供 CSV 和 JSON 下载:数据来源与许可