Key Takeaways
- Duplicate SMS is almost never “the API randomly double-billed.” It is a retry, a replay, or two radios.
- Stable Idempotency-Key per business event is the first fix. A new UUID per HTTP attempt is the bug.
- Webhook retries reuse X-SmsGateway-Event-Id. Unique-constrain it before any auto-reply send.
- Two paired devices without deviceIds can both take a job you thought was singular.
- Duplicates consume operator airtime and platform volume. You do not get that back.
Android sms gateway troubleshooting duplicate sends is a KB, not a feature pitch. Two bubbles on a lock screen, two live OTP codes, two “table ready” texts. Find which layer minted the second job.
Design article: idempotent send. Webhooks: server webhook. Docs: Developer Center.
What duplicate sends look like
- Two GSM bubbles, same body, seconds apart.
- OTP verifier accepts only the second code.
- Panel shows two message ids for one order.
Timeouts are not failures until you have looked up the first message id. Blind retry is how you buy two segments.
HTTP method safety is a client problem; see RFC 9110, then still send a business-stable key.
Cause → check → fix
| Cause | Check | Fix |
|---|---|---|
| HTTP retry, new key | Two POSTs, two Idempotency-Keys | Key = orderId / challengeId; lookup before second POST |
| Webhook echo | Auto-send inside message.delivered | Unique event id; never send on DLR replay |
| Two devices | Both radios online; deviceIds omitted | Pin OTP; do not round-robin auth |
| Queue worker restart | Bulk prefix resent | Per-row keys |
| UI double-submit | Two clicks, two jobs | Disable button; same key both clicks |
HTTP retries
Load balancers retry. The sample send curl already includes Idempotency-Key. A new GUID per attempt defeats it. API.
Webhook-driven echoes
Delivery callbacks retry. If your handler “confirms” by sending another SMS, you will loop. Webhook product page.
Two phones, one job
Failover is good until both are healthy and both send. Multi-device limits. Pin OTP with deviceIds.
Double-tap and workers
Bulk: bulk SMS. Rate-limit UX so the host cannot mash “ready.” Rate limits.
Airtime you already spent
Duplicates bill the operator and the platform meter. Free: 300 SMS lifetime. Developer: 25,000/year. Starter/Pro/Business uncap platform volume, devices 2/5/15. Pause on Free/Developer at allowance. No unlimited carrier SMS. We do not cash out unused operator credit.
Checklist
- One key per business event in logs next to message id.
- Event-id unique index before auto-reply.
- OTP pinned to one deviceId.
- Staging: force a 504 and count bubbles — must stay one.
Next steps
Break your client on purpose. One destination thread, one bubble. Setup · downloads.
Related product pages
Jump to the live product docs for this topic—not another long-form article.
- SMS API documentationLive endpoint reference
- device and SMS volume pricingPlans and allowances
- Android SMS gateway product guideDefinition, product, and how to buy
- download the Android gateway appGet the APK





