EnvlopedDocs

Idempotency

Retry Envloped API requests safely with the Idempotency-Key header

Idempotency

Networks fail in the worst possible place: after the server did the work but before you saw the response. Retrying blindly sends the email twice.

Send an Idempotency-Key header and Envloped remembers the outcome of the request, so a retry with the same key returns the original response instead of performing the operation again.

The header is optional. Requests without it behave exactly as they always have — nothing is recorded and nothing is checked.

Supported endpoints

EndpointWhat a replay returns
POST /v1/emailsThe original send response, including the same id and messageId. No second email is sent.
POST /v1/contacts/batchThe original receipt: the same created / updated / rejected_ineligible counts and the same per-row results.

Keys are scoped per endpoint and per account, so the same key used on /v1/emails and /v1/contacts/batch refers to two independent operations, and another account's key can never collide with yours.

Choosing a key

The key must identify one logical operation, not one HTTP attempt. Generate it once, before the first attempt, and reuse it for every retry of that same operation.

// Good: the key is derived from the thing you are doing.
const key = `booking-${bookingId}-confirmation`

// Also good: a UUID generated once, then reused across retries.
const key = crypto.randomUUID()

for (let attempt = 0; attempt < 3; attempt++) {
  const res = await fetch('https://api.envloped.com/v1/emails', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${apiKey}`,
      'Content-Type': 'application/json',
      'Idempotency-Key': key,          // ← same key on every attempt
    },
    body: JSON.stringify(payload),
  })
  if (res.ok) break
}

A key generated inside the retry loop is fresh on every attempt and dedupes nothing.

Keys may be up to 255 characters. Anything unique is fine — a UUID, or an id from your own database, which has the advantage of surviving your process crashing and restarting.

Responses

StatusWhenWhat to do
2xxFirst time this key was seen.Normal path.
2xx (replay)The key completed earlier. The stored response body is returned verbatim.Nothing — the operation already happened exactly once.
409The key is currently in flight (a first attempt has not finished).Wait and retry; do not treat as failure.
422The key was used before with a different request body.A bug on your side: the same key is being reused for a different operation.

The 422 is deliberate. Reusing one key for two different payloads is ambiguous — Envloped refuses rather than guessing which one you meant.

Sending a batch you can reconcile

For a large contact backfill split across many requests, derive the key from the batch number:

curl -X POST https://api.envloped.com/v1/contacts/batch \
  -H "Authorization: Bearer en_abc123..." \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: members-backfill-2026-08-09-batch-17" \
  -d '{ "contacts": [ /* up to 1000 */ ] }'

If a batch's response never arrives, replay the same request with the same key. Either it runs for the first time, or you get the receipt for the run that already happened. Both outcomes are correct, and you can tell them apart from the counts.

What this does not cover

Idempotency protects against duplicate delivery of the same operation. It does not deduplicate two genuinely different requests that happen to look alike: sending the same email body to the same recipient twice with two different keys sends two emails, by design.

On this page