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 /draftsPOST /emails/bulkPOST /labelsPOST /ai-label-rulesPOST /viewsPOST /filtersPOST /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
| Situation | Response |
|---|---|
| Same key, different body | 409 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 progress | 409 CONFLICT. Retry in a moment. |
| Key longer than 255 characters | 400 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.