Guides
Idempotency & duplicates
Idempotency-Key rules, client_id, duplicate-content detection, loop protection and safe retries, so an agent never sends the same mail twice.
docs.simail.ai/idempotency
Agents retry. Networks time out. simail is built so that a retry never sends a second email.
Idempotency-Key
Section titled “Idempotency-Key”Every POST accepts an Idempotency-Key header. It is required on every send:
messages/send, reply, reply-all, forward and drafts/{draft_id}/send. A send without it
returns 400 validation_error. In MCP, the send tools take idempotency_key instead.
| Situation | Result |
|---|---|
| New key | the request runs normally |
| Same key, same body | the original response is returned; nothing runs again |
| Same key, different body | 409 idempotency_conflict |
| Key from another key or organization | treated as a new key (keys are scoped to your organization and the calling key) |
Keys are kept for 24 hours for ordinary requests and permanently for sends.
Choose keys that describe the intent, not the attempt. Good keys come from your own data:
reply-msg_01JZX…-v1, order-1042-shipped, digest-2026-10-18. Do not use a random value per
attempt; that defeats the point.
client_id
Section titled “client_id”Creating inboxes and pods also accepts client_id. The same client_id in the same organization
always returns the same object, so an agent can “create or get” its inbox at start-up without
keeping state.
Duplicate content
Section titled “Duplicate content”Independently of the key, the release service refuses a message that is identical to one already
sent from the same inbox within the de-duplication window (24 hours by default): same sender, same
recipients, same normalized subject and body. The send returns 409 duplicate_send. Do not
resend with a new key; the earlier message already went out.
Loop protection
Section titled “Loop protection”Two agents, or an agent and an auto-responder, can mail each other forever. The release service
blocks (422 send_blocked):
reasons | When |
|---|---|
loop_auto_reply | replying to an auto-reply, a bounce, or mail sent by another simail agent |
loop_thread | more than 20 exchanges in one thread with the same peer within 24 hours |
loop_peer | more than 40 exchanges with the same peer across threads within 24 hours |
Outbound mail carries Auto-Submitted headers and a simail loop marker, so well-behaved systems
(including other simail inboxes) do not answer it automatically.
When the outcome is unknown
Section titled “When the outcome is unknown”If the mail network does not confirm a send, the send status becomes outcome_unknown. simail
never resends it automatically. When a delivery or bounce event arrives for it, the status is
corrected. A human can check the console; your agent should not try again with a new key.
Retrying safely
Section titled “Retrying safely”| Response | Retry? |
|---|---|
network error, timeout, 500, 503 | yes, with the same Idempotency-Key, after a backoff (Retry-After when present) |
429 rate_limited, 429 daily_limit_exceeded | yes, after Retry-After, same key |
409 idempotency_conflict | no; you changed the body. Use a new key only if you really mean a new message |
409 duplicate_send | no; it was already sent |
422 send_blocked, 423 thread_locked, any 403 | no; read reasons or tell your human |
Every error says retryable: true or false; trust it. See Errors.