Idempotency

Retry a send or a creation safely with the Idempotency-Key header, without doing it twice.

A network timeout does not mean a request failed: the email may have left, and only the response got lost. Retrying blindly would send it a second time. The Idempotency-Key header makes retries safe.

Which requests accept it

Every POST that sends or creates something:

  • POST /drafts/send (send an email)
  • POST /drafts
  • POST /emails/bulk
  • POST /labels
  • POST /ai-label-rules
  • POST /views
  • POST /filters
  • POST /auto-forward-rules

The header is optional. Send it on every one of these requests, and always on POST /drafts/send.

curl -X POST https://api.maylee.app/api/v1/drafts/send \
  -H "Authorization: Bearer $MAYLEE_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"mailboxId":"cmbx1a2b3c4d5e6f7g8h9i0j","to":[{"email":"client@acme.com"}],"body":{"text":"Hello"}}'

How it works

  • The first successful response is stored for 24 hours.
  • Replaying the same key with the same body returns that response with the header Idempotent-Replay: true, without running the operation again.
  • Only successful responses are stored: a failed call releases its key, so that you can retry once the request is fixed.
  • The replay still counts as a request: it is subject to the per-minute rate limit and uses the same quota units as the original call.
  • In the rare event the idempotency store is unavailable, requests go through without the guarantee rather than being refused.

Guard rails

SituationResponse
Same key, different body409 CONFLICT. It is almost always a bug (a key generated once and reused in a loop), and replaying would hide it.
Same key while the original call is still in progress409 CONFLICT. Retry in a moment.
Key longer than 255 characters400 VALIDATION_FAILED

Choosing keys

Keys are scoped to the workspace. Use globally unique values such as UUIDs (uuidgen, crypto.randomUUID(), uuid.uuid4()), never a counter, so that two integrations sharing a workspace cannot collide. Generate a new key for every new operation, and reuse it only to retry that same operation.

On this page