エラーとレート制限

エラーとレート制限

すべてのエンドポイントは、機械可読なコードとリクエストIDを含む共通の形式で失敗を報告します。

エラーレスポンス

呼び出しが失敗するとsuccess: falseが返されます。codeは変更されない安定した値でプログラム向け、errorは人が読むための短い英語メッセージ、request_idは当社のログ上でその呼び出しを特定するIDです。入力に問題がある場合は、paramに該当するパラメータ名が入ります。

実際の例

以下は、このページのレンダリング時にAPIから取得したライブのレスポンスです。

必須パラメータの不足 · GET /api/sd/oi · HTTP 400
{
  "success": false,
  "error": "coin required",
  "code": "INVALID_PARAM",
  "request_id": "cb-mwefrn7e-f4d85d519d"
}
不明なエンドポイント · HTTP 404
{
  "success": false,
  "code": "NOT_FOUND",
  "error": "unknown endpoint: GET /api/this-endpoint-does-not-exist",
  "request_id": "cb-mwefrn7e-de3e82c2fc"
}

エラーコード

コードHTTP意味対処方法
INVALID_PARAM400必須パラメータが不足しているか、値が受け付けられません。該当するパラメータが特定できる場合は、`param`にその名前が入ります。そのまま再試行せず、リクエストを修正してください。
UNAUTHORIZED401`CB-API-KEY`ヘッダーが送信されましたが、キーが不明か失効済みです。公開データにキーは不要です。ヘッダーを外すか、有効なキーを使用してください。そのまま再試行しないでください。
FORBIDDEN403このルートは公開APIに含まれません(内部用またはアカウント専用)。再試行しないでください。
NOT_FOUND404不明なルートであるか、リクエストされた銘柄 / 取引所 / ファンドが存在しません。再試行せず、パスと識別子をカタログと照合してください。
RATE_LIMITED429リクエスト数が1分あたりの上限を超えました。`Retry-After`に待機すべき秒数が示されます。`Retry-After`で示された時間だけ待ってから、バックオフ付きで再試行してください。
INTERNAL500予期しないサーバーエラーです。メッセージは意図的に汎用的な内容にしています。報告の際は`request_id`を引用してください。数秒後に1回だけ再試行してください。解消しない場合は、リクエストIDを添えて報告してください。
UPSTREAM_FAILED503このエンドポイントの背後にあるデータソースが時間内に応答しませんでした。鮮度切れの数値や代替の数値を代わりに返すことはありません。バックオフ付きで再試行し、ステータスページを確認してください。
UNAVAILABLE501 / 503データセットが一時的に準備できていない(キャッシュのウォームアップ中)か、このエンドポイントに適法な公開ソースがまだありません。時間をおいて再試行してください。仕様上利用できないエンドポイントは、カタログに明示されています。
REQUEST_FAILED200一部の古いエンドポイントは、HTTP 200で`success: false`を返します。HTTPステータスだけでなく、必ず`success`を確認してください。メッセージによって異なります。失敗したリクエストとして扱ってください。
古いエンドポイントでは、項目が存在しない場合にHTTP 200でsuccess: falseとコードREQUEST_FAILEDを返すことがあります。すべてのレスポンスでsuccessを確認してください。

リクエストID

各レスポンスにはX-Request-Idヘッダーが付与されます。失敗レスポンスでは、同じ値がボディのrequest_idにも含まれます。短時間のエッジキャッシュから返されたレスポンスは、そのレスポンスを生成したリクエストのIDをそのまま返します。そのため、連続する呼び出しでIDが同一であれば、キャッシュされたコピーを受け取ったことを意味します。

レート制限

制限は1分単位で適用され、匿名の呼び出しではIPアドレスごと、有効なCB-API-KEYヘッダーを送信した場合はキーごとにカウントされます。上限は毎分1200リクエストです。/api/coin-icon配下のアイコンリクエストはカウントされません。

レート制限ヘッダー

名前説明
X-Request-Idこのリクエストの識別子。バグ報告の際に引用してください。
X-RateLimit-Limit現在の1分間ウィンドウで許可されるリクエスト数。
X-RateLimit-Remaining現在のウィンドウで残っているリクエスト数。
X-RateLimit-ResetウィンドウがリセットされるUnix時刻(秒)。
Retry-AfterHTTP 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に記載されます。