Skip to main content
Use one Idempotency-Key for each intended email, SMS/MMS, or iMessage. Reuse that key and the same input if the request times out. Use a new key for a deliberately new message, even if its content is identical. For raw HTTP requests, also send Prefer: idempotency-replay to select the replay contract below. SDKs and CLI version 0.7.10 send this preference automatically. Requests without this preference keep their existing behavior: completed keyed email retries return 409, and SMS/iMessage calls are independent sends. Email and SMS still wait for send acceptance before returning success. iMessage keeps its existing queued acknowledgement. Response shapes and delivery fields are unchanged. The SDKs generate a key for each send call and preserve it during bounded request retries. Pass an explicit key for a workflow that retries across separate calls or processes. The CLI exposes --idempotency-key on email, text, and iMessage sends.

Retry outcomes

Recorded responses include Preference-Applied: idempotency-replay. Idempotency-Rejected: true means the original request was definitively rejected without sending. After correcting that issue, you may explicitly start a new attempt with a new key. Do not infer this from HTTP status alone: a conflict or missing result can refer to a message that was already sent. This includes recorded pre-send iMessage rejections. Authentication or validation failures that cannot establish the original request’s outcome may omit the header. Keys must be nonblank, contain 1–255 printable ASCII characters, and have a seven-day supported response-replay window. Do not intentionally reuse a key for another message. Keys are scoped to your organization, sending resource, and operation. An expired key cannot start a new message; its original response is unavailable. A replay is the original request result, not current delivery tracking. Use the message’s normal get endpoint or delivery webhooks for live status. A successful queued response does not mean the recipient has received the message. Request retries do not guarantee delivery retries. A missing delivery receipt does not justify creating a second message. For 503 send_outcome_ambiguous, respect Retry-After before checking again with the same key. Lookup or outbound history may help, but an interrupted email/SMS request may have no recoverable message ID and can remain unresolved. Never automatically switch keys because a lookup returned 404.

Recover the original message ID

Supply the original key in the Idempotency-Key header, together with your usual authentication. This read-only endpoint does not send or resume a message.
404 means no result is available to you. It does not prove the message was never sent: the original request may still be processing. Do not generate a new key automatically after a missing lookup result. Lookup can return 403 when your credential is not allowed to use the selected channel, or 422 for a missing/invalid key, UUID, sender kind, or operation. An email-address helper resolves the mailbox UUID before performing lookup. An interrupted email or SMS send may remain unconfirmed without a message ID. Reusing its key does not submit another message. After a confirmed rejection that permits retry, the eventual message ID may differ and the email may use your updated mailbox signature from the earlier unsuccessful attempt. Once a final response is available, replays return that original response.

Keep the key after an error

Python exposes get_message_request_key(error) from inkbox; TypeScript exposes getMessageRequestKey(error) from @inkbox/sdk. These recover the generated key from send errors, including transport failures. The CLI prints it in stderr and includes error.idempotencyKey with --json. Rust errors do not expose generated keys. Preserve your own key and use an explicit-key send method when you need to retry or look up the request across calls. Use imessages.get(message_id) in Python, imessages.get(messageId) in TypeScript, or inkbox imessage get <message-id> --identity <handle> to read a recovered iMessage.