錯誤與速率限制
每個端點都以相同的結構回報失敗,並附上機器可讀的錯誤碼與請求 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-mwefrxky-2592812a6c"
}未知的端點 · HTTP 404
{
"success": false,
"code": "NOT_FOUND",
"error": "unknown endpoint: GET /api/this-endpoint-does-not-exist",
"request_id": "cb-mwefrxl6-9d8e3c8733"
}錯誤碼
| 錯誤碼 | 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。