冪等なリクエスト
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ボットを作るを参照してください。
安全な再試行
キーをエラーの再試行のルールと組み合わせてください。最初の試行の前にキーを一度だけ作成し、同じ操作のすべての試行でそれを送信します。