本文へスキップ
Sursa Developers

冪等なリクエスト

Sursaがすでに処理を終えた後で、リクエストが失敗することがあります。接続が切れたり、レスポンスが届く前にプロセスが再起動したりする場合です。同じPOSTをもう一度送信すると、2枚目のカードや2つ目のWebhookが作成されるおそれがあります。冪等キーはこれを防ぎます。

すべてのPOSTとPATCHでIdempotency-Keyヘッダーを送信してください。Sursaは、このキーのリクエストをすでに受け取っている場合、操作をもう一度実行せず、最初に保存したレスポンスを返します。

curl -X POST https://api.sursa.com/v1/cards/text \
  -H "Authorization: Bearer $SURSA_API_KEY" \
  -H "Idempotency-Key: 6f1d2c9e-7b0a-4c43-9a51-0d6c1c1f8e21" \
  -H "Content-Type: application/json" \
  -d '{"title": "Refund policy", "body_markdown": "Refunds are processed within 14 days."}'

繰り返したリクエストには、最初のリクエストと同じステータスとボディが、追加のヘッダー付きで返ります。

HTTP/1.1 200 OK
Idempotency-Replayed: true
X-Request-Id: 01JB7R…

繰り返したリクエストには、それ自身のX-Request-Idが付きます。

キーの選び方

  • 論理的な操作ごとに、UUID v4などの新しいランダムな値を使ってください。「このカードを作成する」「このWebhookを登録する」が1つの操作です。その操作の再試行にはすべて同じ値を使い、別の操作には決して使わないでください。
  • 自社のデータから導いた値は良いキーになります(例:sync-2026-10-24-record-1042)。そうすれば、記憶を失って再起動したジョブも同じキーを送信できます。
  • キーは、1〜255文字の印字可能なASCII文字です。それ以外の値には、コードapi.idempotency_key_invalidとともに400が返ります。

Sursaによるキーの扱い

状況レスポンス
このキーでの最初のリクエスト操作は通常どおり実行されます。
同じキー、同じリクエストで、最初のリクエストが2xxまたは4xxで完了している保存済みのレスポンスがIdempotency-Replayed: true付きで返ります。操作はもう一度実行されません。
同じキーで、最初のリクエストがまだ実行中Retry-After: 1付きの409 api.idempotency_in_progress。待ってから再試行してください。
同じキーで、メソッド、パス、Content-Type、ボディのいずれかが異なる409 api.idempotency_mismatch。キーはすでに別のリクエストで使われています。
最初のリクエストが5xxまたは429で完了したキーは解放されます。そのキーでの次のリクエストは、操作をもう一度実行します。
  • キーの有効期間は24時間です。それを過ぎると、同じキーで新しい操作が始まります。
  • キーは組織ごと、呼び出し元ごとに区別されます。2つの異なるAPIキーが同じ値を使っても、互いに影響しません。
  • 4xxのエラーレスポンスも保存されます。バリデーションに失敗したリクエストは、同じキーで繰り返しても同じように失敗します。リクエストを修正し、新しいキーで送信してください。

キーが必要なリクエスト

メソッドIdempotency-Key
POST、PATCH送信してください。再送のためにレスポンスを保存するエンドポイントには、すべてAPIリファレンスにこのヘッダーが記載されています。
GET、PUT、DELETE不要です。これらのメソッドは性質上、繰り返しても安全です。ヘッダーは受け付けますが、効果はありません。
検索、財務レポート、POST /v1/catalog/resolveなど、読み取りだけを行うPOST受け付けますが、何も保存されません。リクエストは単にもう一度実行されます。

ヘッダーがなくても繰り返して安全な操作もあります。

  • PUT /v1/cards-by-external-id/{external_id}は、自社のIDのカードを作成または置換します。同じ内容で繰り返しても何も変わりません。
  • カスタムソースのドキュメントは、自社のexternal_idで識別されます。同じドキュメントをもう一度送信するとunchangedが返ります。
  • POST /v1/chatのストリーミングの回答では、ヘッダーの代わりにボディのrequest_idフィールドを使います。Q&Aボットを作るを参照してください。

安全な再試行

キーをエラーの再試行のルールと組み合わせてください。最初の試行の前にキーを一度だけ作成し、同じ操作のすべての試行でそれを送信します。