Idempotency
Idempotency prevents duplicate sends when your system retries a request.
How it works
Include an Idempotency-Key header with each send request. The key is a unique string you generate — typically a UUID tied to the business event.
curl -X POST https://truncus.co/api/v1/emails/send \
-H "Authorization: Bearer $TRUNCUS_API_KEY" \
-H "Idempotency-Key: order_12345_invoice" \
-H "Content-Type: application/json" \
-d '{
"to": "user@example.com",
"from": "billing@yourdomain.com",
"subject": "Invoice #1234",
"html": "<p>Your invoice is ready.</p>"
}'
Behavior
If a request with the same idempotency key has already been processed:
- The original
message_idandstatusare returned - No new email is sent
- The response is identical to the original
An idempotency key stays unique for as long as the email record is retained — your plan's retention window (30 days on Free, longer on paid plans). Within that window a replayed key always returns the original result; it does not reset after a fixed 24-hour period. This is separate from content-based deduplication, which matches identical message bodies within a 10-minute window.
When to use idempotency
- Payment confirmations — one email per payment, regardless of retries
- Webhook handlers — safe to retry on delivery failure
- Agent workflows — re-runs produce the same result
- Any send where duplication would affect the recipient
SDK usage
const response = await truncus.emails.send({
to: 'user@example.com',
from: 'billing@yourdomain.com',
subject: 'Invoice #1234',
html: invoiceHtml,
}, {
idempotencyKey: `order_${orderId}_invoice`
})
Key design
A good idempotency key encodes the business event, not the request:
// Good: tied to the event
const key = `payment_${paymentId}_receipt`
// Good: stable across retries
const key = `user_${userId}_welcome`
// Bad: changes on retry
const key = crypto.randomUUID()
The Idempotency-Key header is required. A send request without it is rejected with 400 MISSING_IDEMPOTENCY_KEY.