Loading page...Загружаем страницу...正在加载页面...
AtlasRepo

No Idempotency Key? How I Make Gmail Sends Safe to Retry Anyway

Description and use

Gmail lacks an idempotency key, so a failed send leaves uncertainty about delivery. The solution is to generate a deterministic Message‑ID, store it, query Gmail for that ID, and if ambiguous, move the job to a review queue. This enables safe retries and avoids duplicates.

Problem

Gmail’s messages.send lacks an idempotency-key, so a failed send with no response leaves uncertainty whether the email was delivered.

Outcome

Implementing deterministic Message‑IDs and mailbox reconciliation turns Gmail sends into a safe, retry‑friendly process, reducing duplicate emails and ensuring critical actions are not retried automatically.

Workflow

  • 1. Classify failure into Bucket 1 (definitely not accepted) or Bucket 2 (maybe accepted).
  • 2. For Bucket 1, back off and retry automatically.
  • 3. For Bucket 2, place job in a review queue for human decision.
  • 4. When sending, set a deterministic Message‑ID derived from the job’s dedup key.
  • 5. After sending, query Gmail with messages.list?q=rfc822msgid:<Message‑ID> to check if the message exists.
  • 6. If not found, wait 1–2 minutes and retry the query.
  • 7. If found, count occurrences; if >1, flag duplicate.
  • 8. Store job state in Postgres table ai_jobs with fields id, message_id, state, payload, attempts, claimed_at, provider_ref.
  • 9. Sweeper reconciles mailbox status before re‑sending any job.

Evidence

Gmail's messages.send has no idempotency-key parameter.

Source

Bucket 2 never auto-retries. It lands in a review queue with everything a human needs to decide.

Source

When I build the raw MIME for the send, I set the header myself: Message-ID: <job-9f3a2c1b@yourdomain>

Source

Gmail stores the Message-ID you gave it, so the mailbox becomes your acceptance log.

Source

Caveat 1 — the search index lies for a minute.

Source

  • Record date: 2026-10-11T14:41:22.046Z