最後更新
錯誤
所有非 2xx 的回應都是包含相同四個欄位的 JSON 錯誤格式。請依 code 分支處理、將 message 顯示給使用者、記錄 requestId,並且只在 retryable 為 true 時重試。
錯誤格式
429 Too Many Requests
{ "code": "rate_limit_exceeded", "message": "API key rate limit exceeded.", "requestId": "3f2b6c1e-8a4d-4f0e-9b7a-2d5c1e6f8a90", "retryable": true}| 欄位 | 型別 | 意義 |
|---|---|---|
code | string | 穩定、可供機器判讀的識別碼,採 snake_case。請依此欄位分支處理,絕不要依 message 判斷。 |
message | string | 以英文撰寫、供人閱讀的說明。可以安全地顯示給操作人員看;措辭可能會變動。 |
requestId | string | 由伺服器產生的請求 UUID。聯絡客服時請附上;這是我們在日誌中找到該請求的唯一方式。 |
retryable | boolean | 當相同的請求在稍後不需修改即可能成功時(速率限制、暫時性故障)為 true。其他情況都需要改用不同的請求。 |
狀態碼依然重要
HTTP 狀態碼代表大致的類別(4xx 是你這端的問題,5xx 是我們這端的問題);
code 則是精確的原因。只看狀態碼的用戶端,將無法區分缺少權限範圍與方案未包含模組這兩種情況(兩者都是 403)。處理錯誤
以下就是 RoomScope 主控台本身採用的做法:解析錯誤格式、在回應主體不是 JSON 時改用 http_error,並且只在伺服器將錯誤標示為可重試時,以指數退避方式重試。
class ApiError extends Error { constructor(status, { code, message, requestId, retryable }) { super(message); Object.assign(this, { status, code, requestId, retryable: Boolean(retryable) }); }} async function call(path, init) { const res = await fetch(`https://api.toktokdata.live${path}`, init); if (res.ok) return res.status === 204 ? undefined : res.json(); let envelope = {}; try { envelope = await res.json(); } catch {} throw new ApiError(res.status, { code: "http_error", message: `Request failed (${res.status})`, ...envelope });} // Retry only when the server says so.async function withRetry(fn, attempts = 3) { for (let i = 0; ; i++) { try { return await fn(); } catch (e) { if (!(e instanceof ApiError) || !e.retryable || i === attempts - 1) throw e; await new Promise((r) => setTimeout(r, 500 * 2 ** i)); } }}依狀態分類的錯誤碼
錯誤碼是穩定的;未來可能新增錯誤碼,因此遇到不認得的錯誤碼時,請依其狀態碼處理。API 參考中的每個端點都會列出它可能回傳的錯誤碼。
| 狀態 | 錯誤碼 | 發生時機 | 可重試 |
|---|---|---|---|
| 400 | validation_error | 請求主體或參數格式錯誤。訊息會指出是哪個欄位。 | 否 |
| 400 | invalid_rankings_input | 排行榜:缺少 board、某個值超過 128 個字元,或 limit、leagueTier、period、liveOnly 的值無效。 | 否 |
| 400 | invalid_cursor · invalid_region · invalid_trend_type | 端點不接受的游標、地區(洞察端點需為兩個字母)或趨勢類型。 | 否 |
| 400 | invalid_live_history_input · invalid_alert_input · invalid_dataset · invalid_format | 端點特有的輸入錯誤;訊息會說明需要修正的地方。 | 否 |
| 401 | unauthorized | 金鑰缺少、格式錯誤、不存在、已撤銷或已過期,或工作區已停用。回應會附上 WWW-Authenticate: Bearer。 | 否 |
| 402 | credit_cap_exceeded | 此請求會使本期的支出超過點數上限。 | 否 |
| 403 | insufficient_scope | 金鑰缺少該權限範圍,或該路由僅限主控台使用。 | 否 |
| 403 | module_not_entitled | 工作區的方案未包含 LIVE 或查詢模組。 | 否 |
| 403 | export_format_not_entitled | 方案未包含該匯出格式。 | 否 |
| 404 | not_found | 沒有符合該方法與路徑的路由。 | 否 |
| 404 | creator_not_found · video_not_found · live_session_not_found · alert_not_found · export_not_found | 資源不存在,或屬於其他工作區。 | 否 |
| 409 | export_not_ready · api_key_limit_reached | 匯出檔仍在產生中,或已達方案的金鑰數量上限。 | 否 |
| 429 | rate_limit_exceeded | 金鑰超過每秒請求數上限。請遵守 Retry-After。 | 是 |
| 429 | daily_quota_exceeded | 金鑰已用完每日配額。Retry-After 會倒數至 UTC 午夜。 | 是 |
| 503 | rate_limit_unavailable · metering_unavailable · webhook_unavailable | 某個相依服務無法使用。請以退避方式重試。 | 是 |
| 500 | internal_error | 我們這邊發生錯誤。請以退避方式重試;回報問題時請附上 requestId。 | 是 |
不屬於錯誤的情況
- 在排行榜上指定不明或未覆蓋的
region並不是錯誤:回應會是200,並帶有publishable: false、空的entries清單,以及說明原因的provenance。 - 正在收集中的追蹤中名單、粉絲與留言會回應
202,並帶有status: "collecting"、jobId與Retry-After標頭。請在該秒數過後再次呼叫。
速率限制有專屬頁面:速率限制。
這個頁面對你有幫助嗎?