SMPP: the no-delivery receipt window
When asubmit_sm from your SMPP bind is terminated on another channel — WhatsApp is the common case — no carrier produces a receipt, so Orbit synthesizes one. A receipt that says “nothing confirmed” is only useful if it arrives at a time you chose: this page covers the receipt_timeout_seconds field on a termination rule’s deliver hop, which sets how long the channel has to confirm delivery before your bind receives a UNDELIV receipt you can fail over on.
The model behind the field is defined in Send-side DLR model; this page is the how-to: where to set it, when to change it, and the edge cases.
What the window controls
An accepted absorbed submit arms a deadline at submit time plus the window. If a delivery or read receipt lands before the deadline, it is dispatched to your bind normally and the deadline is consumed. If the deadline expires with no confirmation, the sweep emits astat:UNDELIV receipt whose reason names the armed window — no delivery within 45 s of acceptance — so your fallback logic both fires and can see which window fired it.
The field on the hop:
The default of 30 seconds means an untouched rule behaves exactly as it did before the field existed: nothing about your existing receipts changes until you set a value.
In the dashboard, Developer → SMPP surfaces a No-delivery receipt window panel that previews the deliver-hop field with the same 10–120 bounds and blank-means-default behavior. The panel is a preview today — pick the value there and Support applies it to your rule while the unified rules editor is finalized. The API body below is the same contract you can write immediately.
When to change it
Tune the window against your own traffic’s confirmation curve, not against the platform default:- Raise it (toward 120) when destinations confirm slowly — handsets that wake late, recipients roaming across MNOs, or channels with known receipt lag. A UNDELIV fired at 30 s on a channel that habitually confirms at 40 s trains your fallback to re-send messages that were about to land.
- Lower it (toward 10) when your fallback is the point — OTP and fraud-alert traffic where a fast re-send over a second channel beats the small hit-rate gain from waiting longer.
- Leave it at 30 unless you have measured otherwise. Two tenants disagree on the right value by tens of seconds; the default exists as a safe middle, not a recommendation.
A worked example — absorb onto WhatsApp with a 45-second window
The rule below absorbs SMPPsubmit_sm traffic for +91 destinations onto WhatsApp and sets a 45-second window on the deliver hop:
- At t=0 your
submit_sm(withregistered_deliveryrequesting a receipt) matches the rule and is absorbed onto WhatsApp. A deadline is armed at t=45 s. - If WhatsApp confirms delivery at t=12, a
stat:DELIVRDreceipt is dispatched to your bind at t=12 — the deadline never fires. - If nothing confirms by t=45, the sweep emits
stat:UNDELIVwith the reasonno delivery within 45 s of acceptance, and your failover channel kicks in on exactly that signal.
45 in the field once Support has applied it — the same value the API body carries.
How it interacts with the canonical DLR vocabulary
The window touches exactly one arm of the receipt model: the synthesizedfailed{provider_error} → UNDELIV that fires on deadline expiry. Timing of the timeout arm is all it delays. Everything else is untouched:
- Receipts that arrive before the window dispatch normally — this is a deadline, not a grace period that holds receipts back.
- The failure arm still carries the documented
err:tokens —81(not on destination channel),88(re-engagement required),89(rate limit),00(unspecified provider error) — per Send-side DLR model. - The encodings the bind and the webhook leg produce are identical, per SMPP edge model.
API-side notes
- Optional, default 30. Omitting
receipt_timeout_secondsarms the platform default. Sending the field as blank/absent and sending it as30are equivalent; there is no way to “unset” a rule into a non-default. - Integers only.
25.5fails validation at rule-write time; whole seconds in the 10–120 range only. - Shadow vs. enforce. A shadow-mode rule evaluates and records without moving traffic; the window you set takes effect only once the rule flips to
enforce. Rules without adeliverhop (pureabsorbchains) have nothing to arm and ignore the field. - Receipt requests still govern. The deadline only fires for submissions whose
registered_deliveryflag asked for a receipt; a submission that requested none is not given a timeout receipt either. - Rule-level guard on bind mode. A rule that moves messages off the SMPP ingress can require the credential’s
dlrModeto bewebhookorboth(require_dlr_modeon the rule), so choosing a window never creates a receipt black hole for bind-only credentials.
See also
- Connect via SMPP — bind credentials, DLR delivery modes, and the diagnostic ladder
- Send-side DLR model — the canonical vocabulary and the absorbed-receipt encoder this window tunes
- SMPP edge model — the relay and reconciliation model underneath the bind
- DLR model: two planes, one vocabulary — telling carrier-sourced receipts from synthesized ones