SMSRoute engineering notes

If your application logs status=delivered and you treat that as "the human read the code," you

have a silent failure mode. SMS delivery receipts (DLRs) are a chain of handoffs, and every link

can report success while the message never lands on a handset.

What the chain actually looks like


your API call ──▶ provider accepted ──▶ carrier accepted ──▶ handset ack ──▶ human reads it
     │                   │                     │                  │              │
   201 Created      "queued"/"sent"        "delivered"       (sometimes)     (never observable)

The status you receive usually reflects the furthest point that bothered to report back. Several

carriers return a positive receipt when the message enters their system, not when the phone

acknowledges it. Some return nothing at all and your provider synthesises a value. So:

aggregator, not the handset.

Design rule: three states, not two

Model status as pending | confirmed | failed, and make pending a first-class state with a

deadline rather than an optimistic assumption.


STATUS_MAP = {
    "delivered":   "confirmed",
    "undelivered": "failed",
    "failed":      "failed",
    "rejected":    "failed",
    "expired":     "failed",
    "sent":        "pending",
    "queued":      "pending",
    "accepted":    "pending",
}

def on_callback(evt):
    state = STATUS_MAP.get(evt.status, "pending")     # unknown status → pending, never confirmed
    store.update(evt.message_id, state=state, raw=evt.status, at=evt.timestamp)

Mapping unknown strings to pending rather than confirmed is the entire trick. Providers add new

status values; a permissive default silently turns new failure modes into fake successes.

Handle callbacks like the hostile input they are

Delivery webhooks are public endpoints that assert things about your money and your auth flow.


def handle(request):
    if not verify_signature(request.headers["X-Signature"], request.body, SECRET):
        return 403                                     # 1. authenticate
    evt = parse(request.body)
    if store.seen(evt.event_id):
        return 200                                     # 2. idempotent: retries are guaranteed
    if evt.timestamp < store.last_timestamp(evt.message_id):
        return 200                                     # 3. out-of-order: don't regress state
    apply(evt)
    return 200                                         # 4. ack fast, process async

At-least-once delivery is the norm — you will get the same event twice, and you will get a

delivered after a failed for the same message. Without the ordering guard, a late callback can

flip a correctly-failed message back to confirmed.

The fallback that actually helps users

Don't wait for a failure callback that may never come. Set a timer at send time:


schedule(check_in=timedelta(seconds=45), message_id=msg.id)

def on_timer(msg_id):
    if store.get(msg_id).state == "pending":
        offer_alternative(...)      # voice call, email, authenticator app, "try again"

Forty-five seconds of a spinner is the ceiling before people leave. A pending-with-deadline model

gives you a place to hang that fallback; a two-state model doesn't.

Reconcile, don't trust

Once a day, pull the provider's own record for anything still pending past its window and settle

it. Webhooks get lost — dropped by your load balancer during a deploy, blackholed by a firewall

rule, silently 500'd during an incident. A reconciliation job is thirty lines and turns "we think

it worked" into "we checked."

Why messages fail in ways no status explains

A meaningful share of international non-delivery isn't a technical failure at all — it's a

regulatory one. Many countries require pre-registration of alphanumeric sender IDs before

traffic is accepted; unregistered senders get filtered, often with a positive-looking receipt

upstream. Others ban alphanumeric senders entirely and rewrite them.

We publish what we verify about those rules as an open dataset — regime, registration requirement,

regulatory basis, last-verified date, plus the encoding class per country:

github.com/SMSRoute-cc/sms-sender-id-regulations (CC-BY-4.0, JSON + CSV)

If your delivery rate is fine in nine countries and terrible in the tenth, check the registration

column before you rewrite your retry logic.


*I work on smsroute.cc — the dataset above comes out of operating these

routes. The patterns here are provider-agnostic; MIT-licensed clients if useful:

Python, Node.*