> ## Documentation Index
> Fetch the complete documentation index at: https://docs.livingsecurity.com/llms.txt
> Use this file to discover all available pages before exploring further.

# レート制限

> Living Security Public API のリクエスト上限、429 レスポンスの仕様、および Retry-After を用いた再試行方法について説明します。

`/v1` API では、互いに独立した 2 つのリクエスト上限が適用されます。いずれか一方の上限に達した場合、リクエストは拒否されます。

| 上限 | 適用対象 |
| - | - |
| API キーごと | そのキーを提示するすべてのリクエスト（送信元アドレスを問わない） |
| クライアント IP ごと | そのアドレスからのすべてのリクエスト（認証の有無を問わない） |

API キーごとの上限は、キーが使用される場所にかかわらず、そのキーに対して適用されます。IP ごとの上限は、未認証のトラフィックに対する唯一の上限であり、認証済みトラフィックに対しては 2 つ目の上限となります。

<Note>
  制限は認証の前に適用されるため、無効な認証情報または欠落した認証情報を含むリクエストも、送信元の上限に対してカウントされます。具体的な上限値は運用者によって設定されており、変更される場合があります。以下のレスポンス仕様は安定したインターフェースであるため、これに基づいて実装してください。
</Note>

いずれかの Basic 認証情報の形式で認証します。詳細は[クイックスタート](/ja/developers/v1/quickstart)（`apikey:secret` または `secret:`）を参照してください。
`BASE` には、組織のリージョンのホストを設定します。詳細は[リージョン](/ja/developers/v1/regions)を参照してください。

## 429 レスポンス

上限に達した場合、API は `429 Too Many Requests` を返します。レスポンスには、秒単位の `Retry-After` ヘッダーと、標準の problem-details 形式の本文が含まれます。

```json 429 Too Many Requests theme={null}
{
  "type": "https://docs.livingsecurity.com/developers/v1/errors/rate_limited",
  "title": "Too Many Requests",
  "status": 429,
  "detail": "Rate limit exceeded. Retry after the Retry-After interval.",
  "code": "rate_limited",
  "request_id": "req_...",
  "doc_url": "https://docs.livingsecurity.com/developers/v1/errors/rate_limited",
  "retryable": true
}
```

レスポンスには、どちらの上限に達したかは示されません。すべての `429` を同様に扱い、待機してから再試行してください。

## 429 の処理

<Steps>
  <Step title="Retry-After に従う">
    再試行する前に、少なくとも `Retry-After` ヘッダーに示された秒数だけ待機してください。それより早く再試行しても、拒否されるリクエストで上限を再び消費するだけです。
  </Step>

  <Step title="繰り返し発生する場合は指数バックオフを使用する">
    再試行が再度拒否された場合は、バックオフ時間を増やし、ランダムなジッターを加えて、並列ワーカーが同時に再試行しないようにします。ローカルの上限に合わせてサーバーの `Retry-After` を短縮することは決してしないでください。サーバーが、再試行の許容範囲を超える待機を求めている場合は、再試行を中止し、処理を後で実行するようスケジュールしてください。
  </Step>

  <Step title="リクエストレートを平準化する">
    バースト的な送信よりも、一定のリクエストレートを維持してください。一括読み取りの場合は、最大ページサイズ（`limit=500`）を使用すると、より少ないリクエスト数でコレクション全体を取得できます。詳細は[ページネーション](/ja/developers/v1/pagination)を参照してください。複数の一覧取得を並列で実行する場合（たとえば Power BI のテーブルなど）は、同時実行数を控えめに保ち、`Retry-After` に従って、一時的な 429 によって更新全体が失敗しないようにしてください。
  </Step>
</Steps>

この例では、**GET** リクエストに対する `429` レスポンスのみを再試行します。試行は最大 5 回、試行間の待機は最大 60 秒です。その他のエラーでは直ちに停止します。ネットワークのタイムアウトは呼び出し元に伝播されます。タイムアウトと再試行の上限は、ワークロードに合わせて設定してください。`requests` は、読み取りタイムアウトを全体の期限ではなく、データ受信中の最大アイドル時間として解釈します。

`LIVING_SECURITY_API_KEY` はシークレットマネージャーから読み込んでください。この例を実行する前に、`requests` をインストールしてください。使用するには `get_with_retry("/organization")` を呼び出します。

```python Python theme={null}
import os
import random
import time
import requests

# US: BASE = "https://api.us-east-1.livingsecurity.ai/v1"
BASE = "https://api.eu-west-1.livingsecurity.ai/v1"
AUTH = ("apikey", os.environ["LIVING_SECURITY_API_KEY"])

def get_with_retry(path, params=None, max_attempts=5):
    if not 1 <= max_attempts <= 5:
        raise ValueError("max_attempts must be between 1 and 5")
    for attempt in range(max_attempts):
        response = requests.get(
            f"{BASE}{path}", auth=AUTH, params=params,
            headers={"Living-Security-Version": "2026-07-01"},
            timeout=(5, 30), allow_redirects=False,
        )
        if response.status_code != 429:
            response.raise_for_status()
            if not 200 <= response.status_code < 300:
                raise RuntimeError("Unexpected redirect; check your regional API URL")
            return response

        # The API returns Retry-After as a whole number of seconds.
        raw_wait = response.headers.get("Retry-After", "")
        request_id = response.headers.get("Request-Id", "unknown")
        response.close()
        if attempt == max_attempts - 1:
            raise RuntimeError(f"Retry budget exhausted; request_id={request_id}")
        if not raw_wait.isascii() or not raw_wait.isdigit() or len(raw_wait) > 6:
            raise RuntimeError(f"Invalid Retry-After; request_id={request_id}")

        wait = max(int(raw_wait), min(2 ** attempt, 30))
        delay = wait + random.uniform(0, 1)
        if delay > 60:
            raise RuntimeError(f"Retry-After exceeds wait budget; request_id={request_id}")
        time.sleep(delay)
```

このループを書き込み操作にそのまま適用しないでください。書き込み後のタイムアウトは、接続が失敗する前にサーバーが書き込みをコミットした可能性があることを意味します。書き込みを再実行するのは、その操作のリファレンスで冪等性が明示的に記載されている場合に限り、同じキーとペイロードを維持して行ってください。それ以外の場合は、再試行する前にリソースの状態を照合してください。

## 推奨される更新スケジュール

更新頻度は、API キーの上限とページサイズに照らして決定してください。大規模なコレクションの全履歴の読み込みは一度限りのコストです。定常的な更新では増分ウィンドウを使用し、各実行が上限を大きく下回るようにしてください。`limit=500` は必ず明示的に設定してください。デフォルトの 25 ではリクエスト数が大幅に増加します。


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.