幂等请求
请求可能在 Sursa 已经完成工作之后才失败:连接断开,或者您的进程在收到响应前重启。如果再次发送同样的 POST,可能会创建第二张卡片或第二个 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。
选择键
- 每个逻辑操作(“创建这张卡片”“登记这个 Webhook”)使用一个新的随机值,例如 UUID v4。该操作的每次重试都使用同一个值,绝不用于其他操作。
- 如果有自己的数据,最好由数据生成键,例如
sync-2026-10-24-record-1042。这样即使作业重启后丢失了内存中的状态,也会再次发送同一个键。 - 键由 1–255 个可打印 ASCII 字符组成。其他值会返回
400,错误码为api.idempotency_key_invalid。
Sursa 如何处理键
| 情况 | 响应 |
|---|---|
| 第一次收到带有这个键的请求 | 照常执行操作。 |
同一个键、同样的请求,第一次以 2xx 或 4xx 结束 | 返回已保存的响应,带有 Idempotency-Replayed: true。不会再次执行操作。 |
| 同一个键,第一个请求仍在执行 | 返回 409 api.idempotency_in_progress,带有 Retry-After: 1。等待后重试。 |
同一个键,但方法、路径、Content-Type 或正文不同 | 返回 409 api.idempotency_mismatch。该键已被另一个请求占用。 |
第一个请求以 5xx 或 429 结束 | 键被释放:下一个带有该键的请求会再次执行操作。 |
- 键的有效期为 24 小时。过期后,同一个键会开始一个新操作。
- 键按组织和调用方分开:两个不同的 API 密钥可以使用相同的值,互不影响。
4xx错误响应也会保存。未通过校验的请求用同一个键重复发送时,会以同样的方式失败;请修正请求,并用新的键发送。
哪些请求需要幂等键
| 方法 | Idempotency-Key |
|---|---|
POST、PATCH | 需要传入。凡是会保存响应以供重复请求使用的接口,API 参考中都列出了该请求头。 |
GET、PUT、DELETE | 不需要:按语义,这些方法本身就可以安全重复。传入该请求头也会被接受,但没有作用。 |
只读取数据的 POST,例如搜索、财务报告和 POST /v1/catalog/resolve | 会被接受,但不保存任何内容:请求只是再执行一次。 |
有些操作即使不带该请求头也可以安全重复:
PUT /v1/cards-by-external-id/{external_id}创建或替换带有您的 ID 的卡片;内容相同的重复请求不会更改任何内容。- 自定义数据源的文档以您的
external_id为键;再次发送同一个文档会返回unchanged。 POST /v1/chat的流式回答使用请求体中的request_id字段,而不是该请求头。参见构建问答机器人。
安全地重试
把幂等键和错误中的重试规则结合起来:在第一次尝试之前创建一次键,同一操作的每次尝试都带上它。