Last updated: 2026-03-033 min read

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_id and status are returned
  • No new email is sent
  • The response is identical to the original

Idempotency keys expire after 24 hours. After expiry, the same key triggers a new send.

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()

If you don't include an idempotency key, each request is treated as a new send.

Idempotency | Truncus Manual