Message Idempotency at Scale: Preventing Duplicate SMS and WhatsApp Sends
A duplicate SMS is almost never the gateway sending twice. It is your application submitting twice, because a network timeout told you nothing about whether the first POST was accepted.
SMSGatewayCenter's engineering guide builds an idempotent send path for bulk SMS, OTP, and WhatsApp in India.
Core idea: Derive a deterministic business key from the event that caused the message. Claim that key in a durable store with a uniqueness constraint before you open the HTTP connection. Treat the claim, not the HTTP response, as the record of truth.
Seven layers that generate duplicates:
User (Resend OTP taps)
Application entry point (double submit, webhook retry)
HTTP client library (urllib3 Retry on POST)
Queue (Celery acks_late, BullMQ stalled jobs)
Ambiguous timeout (read timeout after body sent)
Batch boundary (timeout on 5,000 recipients)
Operator SMSC retransmission (detect, cannot fully prevent)
duplicatecheck=true only collapses the same number appearing twice in one recipient list. It does not remember a request from ten seconds ago.
Also covered: two-level keys, claim-before-send, batch semantics, SMS/WhatsApp fallback, OTP constraints, DLR reconciliation, and a 10-step idempotent send path.
Read: https://www.smsgatewaycenter.com/blog/message-idempotency-preventing-duplicate-sends/








