Sandbox Magic Numbers
Orbit’s sandbox simulator routes every send through a deterministic rule keyed by the trailing digit of the recipient number, so you can exercise your delivery-receipt (DLR), retry, and dead-letter handling without touching a real carrier. Every send is keyed by the trailing digit of the recipient number. Send to+15005550005 and you receive an expired delivery receipt; send
to +15005550003 and you receive undelivered; send to +15005550001
and the carrier only ACKs the submit and never reports a final state — so
you can exercise your DLR-timeout handling. Each scenario walks the same
intermediate→terminal sequence a real carrier produces.
The simulator only activates when:
- The API key is a sandbox key (prefix
dv_test_sk_*), or - The organisation has
is_sandbox = truein the Orbit data plane, or - The request carries the
X-Test-Mode: trueheader from the dashboard.
Message sends — the delivery-state table
The trailing digit of the recipient selects one of ten delivery scenarios. Each scenario emits its full delivery-receipt sequence asmessage.status webhooks — an intermediate sent acknowledgement (when
the message reaches the carrier) followed by the terminal outcome:
Each webhook carries a
state_class (intermediate or terminal) and an
is_terminal flag so your handler can tell an in-flight update from a
final outcome — the same tags the production delivery-receipt path stamps.
The trailing-0 (carrier rewrite) terminal receipt also carries
body_rewritten_by_carrier: true, mimicking regulatory sender-ID rewrites.
Delivery receipts do not change your stored message — a sandbox send
never reaches a carrier, so the message keeps its honest test_sent
status rather than being promoted to delivered/failed. The receipts
appear only in the webhook payloads sent to your sandbox webhook URL,
never on the message you retrieve through the API.
Any E.164 number with the same trailing digit triggers the same
scenario — +15005550009, +15555550009, and +908505550009 all
resolve to the delayed-then-delivered sequence.
Example: simulate a failed delivery
message.status event
with data.status: "failed", state_class: "terminal" — no real carrier
is touched, no balance is deducted.
Example: simulate a delivered message
message.status events in order: an
intermediate data.status: "sent" (state_class: "intermediate"), then
data.status: "delivered" (state_class: "terminal").
Voice calls
simulateCall keys on the trailing digit too, but with three outcomes:
The simulated lifecycle (
call.initiated → call.answered →
call.ended) fires through the same sandbox-events worker.
Reference catalog: GET /sandbox/numbers
Orbit also publishes a 10-state magic-number catalog for clients that
want to render their own developer surface (e.g. an embedded “Test your
integration” widget). This is a descriptive reference table returned
by the read-only GET /sandbox/numbers endpoint and serialised from
SANDBOX_MAGIC_NUMBERS in @devotel/messaging/sandbox/magic-numbers.
These ten states are the same scenarios the live send/DLR path fires
(see the delivery-state table above). The catalog is a
machine-readable copy of that mapping so you can render your own
developer surface — e.g. an embedded “Test your integration” widget —
without hard-coding the digits and latency bands yourself.
submitted, delivered,
undelivered, failed, expired, unknown, rejected, blocked,
delayed, and carrier_rewrite, each keyed by trailing digit
(1–0). See SANDBOX_MAGIC_NUMBERS for the canonical example numbers,
latency bands, and descriptions.
Hard rules
- No real carrier is ever reached. Every magic-number send short-circuits before the provider router resolves a backend.
- No balance is deducted. Sandbox sends always have
cost_usd_cents: 0and never reach Stripe or your wallet. - DLRs fire to your sandbox webhook URL only. Configure this separately from your live URL under Settings → API Keys → Sandbox so production handlers never see test traffic.
- Channels covered: SMS, MMS, WhatsApp, RCS, Viber, Telegram,
Messenger, AMB, Email. Channel-specific status codes (e.g.
WhatsApp
131047) are out of scope for the magic-number convention; the trailing-digit rule maps to the canonical generic status set.