幂等键
网络总会出故障。如果请求超时,你无法判断邮件是否已被接受。发送 Idempotency-Key 标头后即可放心重试:相同的键加相同的请求体,会返回原始响应,并且邮件只会发送一次。
import { SpacePost } from "@spacepost/node";
const spacepost = new SpacePost(process.env.SPACEPOST_API_KEY);
const { data, error } = await spacepost.emails.send( { from: "Acme <hello@acme.com>", to: "user@example.com", subject: "Receipt", html: "<p>Thanks</p>" }, { idempotencyKey: "receipt-order-1042" },);
console.log(error ?? data);curl -X POST https://api.spacepost.dev/emails \ -H "Authorization: Bearer $SPACEPOST_API_KEY" \ -H "Idempotency-Key: receipt-order-1042" \ -H "Content-Type: application/json" \ -d '{ "from": "Acme <hello@acme.com>", "to": ["user@example.com"], "subject": "Receipt", "html": "<p>Thanks</p>" }'requests.post( "https://api.spacepost.dev/emails", headers={ "Authorization": f"Bearer {os.environ['SPACEPOST_API_KEY']}", "Idempotency-Key": "receipt-order-1042", }, json={"from": "Acme <hello@acme.com>", "to": ["user@example.com"], "subject": "Receipt", "html": "<p>Thanks</p>"},)- 支持
POST /emails和POST /emails/batch。 - 键的长度为 1 到 256 个字符。
- 键的作用域为你的团队,并会保留 24 小时。
- 相同的键和相同的请求体:返回已存储的响应(状态码和响应体都相同),不会发送任何新邮件。
- 相同的键但请求体不同:返回
409 invalid_idempotent_request。 - 第一个请求仍在处理时又收到相同的键:返回
409 concurrent_idempotent_requests。请稍等片刻再重试。 - 长度不在 1 到 256 个字符范围内的键:返回
400 invalid_idempotency_key。 - 失败的请求不会被存储,因此你可以修复问题后重用该键。
“相同的请求体”指解析后的 JSON 完全一致。修改任何字段都算作不同的请求,包括 scheduled_at: "in 1 hour"(它在请求时才求值)。
请根据业务事件生成键,而不是在重试时生成随机值:
| 推荐 | 不推荐 |
|---|---|
receipt-order-1042 |
每次尝试都调用 crypto.randomUUID() |
welcome-user-u_1042 |
Date.now() |
digest-2026-w43-chunk-3 |
所有邮件都使用同一个常量 |