Sandbox & test numbers
Test keys (ssms_sk_test_) run against a fully simulated environment: no
carrier traffic, no charges, and nothing real ever sent. Every endpoint works,
so you can build your whole integration, including webhooks, before going
live.
Your sandbox number
Signup provisions a sandbox number in the reserved +1 500-555-XXXX range.
It's the from for outbound tests and the to for simulated inbound. You can
"purchase" more from GET /v1/numbers/available + POST /v1/numbers; the
whole numbers API works in the sandbox.
Your own phone
The console asks for your cell once, right after signup, and texts you a code.
Once it's verified, a test key delivers to that one number for real, so
your first API call makes your phone buzz. Every other destination stays
simulated. Real sandbox texts are capped at 10 a day and end with
- via SimpleSMS sandbox. The response is a normal message with "test": true
and an X-Sandbox-Real-Delivery: true header. Your phone also counts as your
first verified recipient when you go live on the free tier.
Magic destination numbers
Send to these numbers to trigger fixed behaviors:
| Number | Behavior |
|---|---|
+15005550006 | Delivered: message.sent then message.delivered; the message is delivered by the time the send returns. Any other number behaves the same. |
+15005550013 | Delayed delivery: status sent, then really delivered at least 5 seconds later. Poll GET /v1/messages/{id} (it settles as soon as the delay has passed) or wait for the message.delivered webhook (within about a minute). Use it to test code that waits on delivery. |
+15005550001 | Stuck: status stays queued forever, no delivery event. |
+15005550002 | Failed, no reason given: failure.code unknown. |
+15005550007 | Failed: filtered as spam, failure.code carrier_filtered. |
+15005550008 | Failed: refused by the carrier, failure.code carrier_rejected. |
+15005550009 | Failed: number not in service, failure.code invalid_number. |
+15005550010 | Failed: a landline, failure.code landline (and GET /v1/lookup says landline). |
+15005550014 | Failed: phone unreachable, failure.code unreachable. |
+15005550011 | Opted out: 403 forbidden, exactly as for a recipient who replied STOP. Nothing is written to your opt-out list. |
+15005550012 | Rate limited: 429 rate_limited with a Retry-After header. Nothing is stored. |
Failed numbers return 201 with status failed and emit message.sent
then message.failed; the failure object and the event payload are the
same ones a real carrier failure produces (see Errors).
Every sandbox message has a full timeline, segments, encoding,
a price of 0, and destination_carrier from the sandbox lookup.
Simulated inbound
POST /v1/test/inbound delivers a fake inbound SMS to one of your sandbox
numbers through the real pipeline: it appears in GET /v1/messages and emits
a message.received event. (Test keys only; live keys get a 403
test_mode_only.)
Sandbox limits
A ceiling of 1,000 messages/day per account keeps the sandbox healthy. It's not a product quota. If you legitimately hit it, tell us.