レート制限

Listings と Social 全体に適用されるプラン別のリクエスト制限、429 レスポンスの形式、バックオフと再試行の方法について説明します。

Listings API は、アカウントごとのリクエスト数を計測し、ご利用のプランのレート制限を適用します。制限内に収めることで連携の応答性を維持でき、制限を超えた場合は、適切に再試行するために必要な情報をすべて含む 429 Too Many Requests が返されます。

プラン別の制限

有料プランを契約せずに API を試す場合は、無料のサンドボックスデイパスを利用できます。デイパスの利用開始時に、現在適用されるリクエスト制限が API キーとともに返されます。

制限はプランに基づき、アカウントごとに適用されます。同じアカウントのすべての API キーが、同じリクエスト枠を消費します。リクエストは、1 分あたりのバースト制限、1 時間あたりの制限、1 日あたりの上限という 3 つの時間枠で計測されます。エンドポイントにかかわらず、すべてのリクエストが同じ量の枠を消費します。無料トライアルには選択したプランが適用されるため、最初のリクエストからそのプランの制限が適用されます。

プラン1 分あたりの制限1 時間あたりの制限1 日あたりの制限
Launch10 リクエスト/分600 リクエスト/時間7,200 リクエスト/日
Growth50 リクエスト/分3,000 リクエスト/時間36,000 リクエスト/日
Enterprise契約ごとに設定契約ごとに設定契約ごとに設定

Social も同じリクエスト枠を消費します

Social エンドポイントも、ほかのすべてのエンドポイントと同じアカウント単位のリクエスト枠で計測されます。500 行を含む POST /social/bulk-posts が消費するのは 500 リクエスト分ではなく 1 リクエスト分なので、大量のコンテンツを読み込むには一括処理が最も少ないリクエスト消費で済みます。

Listings と Social は別々のサブスクリプションですが、リクエスト枠は別々ではありません。両方を契約しているアカウントには、2 つのプランのうち高い方の制限がすべてのエンドポイントを通じて一度だけ適用されます。制限の合算でも、製品ごとに個別の枠が設けられるわけでもありません。Listings Launch と Social Growth を利用しているお客様のすべてのトラフィックには、上記の Growth の数値が適用されます。

429 レスポンス

制限を超えると、API は HTTP 429 と標準のエラーレスポンスを返します。再試行には、次の 3 つのフィールドが重要です。

  • retry_after_seconds:再試行するまでの待機時間です。Retry-After HTTP ヘッダーが存在する場合は、同じ値が含まれます。
  • correlation_id:サポートに問い合わせる際に伝えるリクエスト識別子です。
  • doc_url:エラーコードリファレンスの rate_limited の項目へのリンクです。
JSON
{  "error": {    "code": "RATE_LIMITED",    "message": "Too many requests. Slow down.",    "retry_after_seconds": 30,    "correlation_id": "9f2c1e64-2b1a-4b0e-9f1a-2c7d5e8a1b3c",    "doc_url": "https://listingsapi.com/docs/error-codes#rate_limited"  }}

バックオフによる 429 への対処

retry_after_seconds が存在する場合はその値に従い、それ以外の場合は指数バックオフを使用します。429 が連続して返されるたびに、上限に達するまで待機時間を 2 倍にし、多数のクライアントが一斉に再試行しないよう、少量のランダムなジッターを加えます。

Python
import randomimport time import requests MAX_RETRIES = 5  def get_with_backoff(url: str, headers: dict, max_retries: int = MAX_RETRIES):    for attempt in range(max_retries):        resp = requests.get(url, headers=headers)        if resp.status_code != 429:            resp.raise_for_status()            return resp.json()         # Prefer the server's hint; fall back to exponential backoff + jitter.        body = resp.json().get("error", {})        retry_after = body.get("retry_after_seconds")        if retry_after is None:            retry_after = min(2 ** attempt, 30) + random.uniform(0, 1)        time.sleep(retry_after)     raise RuntimeError("Still rate limited after retrying")

制限内に収める方法

  • 一度に 1 ページずつリクエストしてください。短い間隔でページを並列取得するループは、429 の最も一般的な原因です。pageInfo.hasNextPage を読み取り、現在のページのレスポンスが返ってから次のページを取得してください。
  • すべてのページを取得してクライアント側で行を破棄するのではなく、filter クエリパラメーターを使用してサーバー側で絞り込んでください。
  • 変更頻度の低いレスポンスは、リクエストのたびに再取得せず、キャッシュしてください。