Avoiding duplicate sends
Operations
What to do when your agent retries a send and you're not sure whether the first one went through.
The scenario
Agent calls POST /send. The response times out. Did the message go or not? Naive retry risks sending twice.
Use an Idempotency-Key
Every send endpoint accepts an Idempotency-Key header: /send, /reply/{messageId}, /reply-all/{messageId}, /forward/{messageId} and /drafts/{draftId}/send. Generate a unique value (a UUID works) once per intended send, and reuse it on every retry of that send.
curl -X POST https://anjal.app/v1/inboxes/$ID/send \
-H "X-API-Key: ak_..." -H "Content-Type: application/json" \
-H "Idempotency-Key: 6f1c2a4e-9b1d-4c1e-8f3a-2d9e7b5c0a11" \
-d '{"to": "lead@acme.com", "subject": "Hi", "plainBody": "...", "verified": true}'
- Same key, identical request: you get the stored response of the first send, with the header
Idempotent-Replayed: true. Nothing is sent again. - Same key, different request (body, inbox or endpoint):
409 IDEMPOTENCY_KEY_REUSED. - Same key while the first request is still running:
409 IDEMPOTENCY_IN_PROGRESS. Wait a moment and retry with the same key. - Header present but blank (or over 255 characters):
400 IDEMPOTENCY_KEY_INVALID. - The first send failed (any non-2xx): the key is freed, so a retry with the same key sends normally.
Keys are scoped to your account and expire after 24 hours. MCP send tools take the same value as an idempotencyKey argument.
Without a key
- If a
POST /sendcall times out or returns a 5xx and you sent no key, don't retry immediately. List recent outbound messages (?direction=outbound&limit=10) and look for a matchingsubjectandtofirst. - Drafts are another safe staging step: the second
POST /drafts/{id}/sendcall returns a 404 because the first one deleted the draft.