错误与速率限制
所有端点均以相同格式报告失败,并附带机器可读的错误码和请求 ID。
错误响应
调用失败时返回 success: false。code 保持稳定,供程序使用;error 是供人阅读的简短英文信息;request_id 用于在我们的日志中定位该次调用。当问题出在输入上时,param 会指出有问题的参数。
真实示例
以下为实时响应,在渲染本页面时从 API 获取。
缺少必填参数 · GET /api/sd/oi · HTTP 400
{
"success": false,
"error": "coin required",
"code": "INVALID_PARAM",
"request_id": "cb-mwefrrsx-0a5b9197d4"
}未知端点 · HTTP 404
{
"success": false,
"code": "NOT_FOUND",
"error": "unknown endpoint: GET /api/this-endpoint-does-not-exist",
"request_id": "cb-mwefrrsy-e11c93374f"
}错误码
| 错误码 | HTTP | 含义 | 处理方式 |
|---|---|---|---|
| INVALID_PARAM | 400 | 缺少必填参数,或某个取值不被接受。已知是哪个参数时,`param` 会给出其名称。 | 请勿原样重试;请修正请求。 |
| UNAUTHORIZED | 401 | 已发送 `CB-API-KEY` 请求头,但该密钥未知或已被吊销。公开数据无需密钥,请去掉该请求头或使用有效密钥。 | 请勿原样重试。 |
| FORBIDDEN | 403 | 该路由不属于公开 API(内部或仅限账户使用)。 | 请勿重试。 |
| NOT_FOUND | 404 | 未知路由,或所请求的币种 / 交易所 / 基金不存在。 | 请勿重试;请对照目录检查路径和标识符。 |
| RATE_LIMITED | 429 | 请求数超过每分钟限额。`Retry-After` 给出需要等待的秒数。 | 等待 `Retry-After` 指定的时间后,再以退避方式重试。 |
| INTERNAL | 500 | 意外的服务器错误。错误信息有意保持通用;报告问题时请附上 `request_id`。 | 几秒后重试一次;若问题持续,请附上请求 ID 报告。 |
| UPSTREAM_FAILED | 503 | 该端点背后的数据源未及时响应。不会返回过期数据或替代数值来顶替。 | 以退避方式重试;并查看状态页。 |
| UNAVAILABLE | 501 / 503 | 数据集暂时未就绪(缓存预热中),或该端点尚无合法的公开数据源。 | 请稍后重试;目录会标出因设计原因而不可用的端点。 |
| REQUEST_FAILED | 200 | 部分较旧的端点会以 HTTP 200 返回 `success: false`。请务必检查 `success`,而不只是 HTTP 状态码。 | 取决于具体信息;按请求失败处理。 |
对于不存在的条目,旧版端点可能返回 HTTP 200 并附带 success: false 和错误码 REQUEST_FAILED。请对每个响应都检查 success。
请求 ID
每个响应都带有 X-Request-Id 响应头。失败的响应还会在响应体中以 request_id 重复该值。由短时边缘缓存返回的响应会沿用生成该响应的原始请求的 ID,因此连续调用得到相同的 ID 说明你收到的是缓存副本。
速率限制
限制按分钟计算:匿名调用按 IP 地址计数,携带有效 CB-API-KEY 请求头时按密钥计数。上限为每分钟 1200 次请求。/api/coin-icon 下的图标请求不计入。
速率限制响应头
| 名称 | 说明 |
|---|---|
| X-Request-Id | 本次请求的标识符。提交问题报告时请附上。 |
| X-RateLimit-Limit | 当前一分钟窗口内允许的请求数。 |
| X-RateLimit-Remaining | 当前窗口内剩余的请求数。 |
| X-RateLimit-Reset | 窗口重置的 Unix 时间,单位为秒。 |
| Retry-After | 随 HTTP 429 返回:重试前需等待的秒数。 |
| X-Cache | 服务端响应缓存的状态:HIT、STALE 或 MISS。 |
超出限制时
API 返回 HTTP 429,错误码为 RATE_LIMITED。请等待 Retry-After 给出的秒数后再重试。轮询频率高于端点的缓存 TTL 只会得到相同的缓存响应,因此请让轮询间隔与各参考页面所示的 TTL 保持一致。
退避重试
JavaScript
async function getJson(url, tries = 4) {
for (let i = 0; i < tries; i++) {
const res = await fetch(url);
if (res.status === 429 || res.status >= 500) {
const wait = Number(res.headers.get("Retry-After")) || 2 ** i;
await new Promise((r) => setTimeout(r, wait * 1000));
continue;
}
const body = await res.json();
if (body.success === false) {
throw new Error(body.code + ": " + body.error + " (" + body.request_id + ")");
}
return body;
}
throw new Error("gave up after " + tries + " attempts");
}没有数据不是错误
当参数有效但该数据没有合法的公开来源时,调用仍以 HTTP 200 成功返回:数值字段为 null,meta.quality 为 UNAVAILABLE,coverage.unavailable 列出原因。请将其渲染为短横线,不要转换为 0。
过期数据
如果采集器出现滞后,端点会继续返回最后入库的数值并标记 meta.is_stale: true,直到这些数值超出可用窗口;此后它们会从聚合值中剔除,并列入 coverage.stale_excluded。