Sandbox API Cookbook
Every sandbox route the sandbox overview catalogs, shown as a runnable request/response pair. The sandbox and test mode guide walks the concepts end to end; this page is the recipe sheet you keep open while you script against the sandbox. All examples use your sandbox secret key, exported as an environment variable:1. Setup — what puts a request in sandbox mode
Any one of these three signals activates sandbox mode; the mutation routes below gate on them before touching data. You usually need exactly one. Signal A — a sandbox API key (the normal one for scripts):X-Test-Mode: true header (dashboard sessions only —
the Test/Live toggle sets it for you):
/sandbox/numbers and /sandbox/pre-launch-checklist
do not gate on the signal (any authenticated key can read them), but every
POST below refuses a non-sandbox context with 403 SANDBOX_ONLY. See the
failure modes section for the envelope.
2. Provision test numbers
Mint deterministic fictional+1 (555) 01XX numbers into your sandbox
inventory. No carrier is touched — the rows write straight into your
tenant with provider: "sandbox" and monthly_cost: "0.0000".
countcaps at 25 per call (MAX_PROVISION_NUMBERS);country_code(2-letter, defaultUS) andcapabilities(a non-empty subset ofsms/voice/mms) are optional.- The numbers are deterministic per tenant — a reset-then-provision run gets the identical inventory, and re-provisioning the same count is idempotent (the deterministic number is the conflict key, so it upserts rather than duplicates).
count above 25 (or 0, or non-integer) fails validation
with a 400; an omitted body defaults count to 5.
3. Spawn fixture contacts
Seed deterministic contacts (Ada Lovelace, Grace Hopper, …) so your inbox, auto-responder, and segment flows have something to work against. Each fixture’s phone ends in the trailing digit of one of the 10 magic numbers, so every delivery scenario has a ready-made recipient.countcaps at 50 per call (MAX_FIXTURE_CONTACTS); an omitted body defaults to 10 contacts.with_conversationsdefaults totrue. With it on, each contact gets one open inbound SMS conversation carrying a greeting message, so the Inbox has a live thread immediately. Set it tofalsewhen you want bare contacts.- Fixture contacts are tagged
sandbox-fixture, which is whatPOST /sandbox/resetsweeps away with the rest of the workspace.
4. Virtual Phone — inject an inbound message
Simulate the handset replying to you: the message lands in your sandbox inbox exactly like a real inbound provider webhook, without forging one. Use it to drive auto-responders, STOP keywords, inbox routing, and the unassigned-notification path.channelaccepts onlysms,mms, orwhatsapp(defaultsms).- The call is rejected (
400 VALIDATION_ERROR) unless it carries a non-emptybodyor amedia_url(anhttps://URL, max 2048 chars, for an MMS / WhatsApp media message).bodycaps at 1600 characters. frommust be E.164;tois optional (defaults to thesandboxsentinel).contact_namesets the display name on a freshly created contact.- Repeat injections from the same sender on the same channel thread into
the open conversation (
created_conversation: false), matching the real inbound path.
created_contact / created_conversation flags tell you
whether this injection minted rows or threaded into existing ones — the
same distinction the live recorder reports.
5. Reset the sandbox
Wipe the sandbox workspace back to a clean slate in one transaction — every contact, conversation, and message, plus every sandbox-provisioned number released. Your API keys, saved test recipient, and sandbox webhook URL survive (they are org settings, not workspace data).6. Magic numbers catalog
The 10 delivery-state scenarios, keyed by the recipient’s trailing digit. Any authenticated key reads it; the dashboard’s magic-number table renders exactly this list.7. Pre-launch checklist
The shared five-step go-live gate — callable with either a live or sandbox key, and always evaluated against your live workspace so both contexts agree on the result.readyForLaunch — it flips to true only when every item reports
status: "complete". Wire it into launch scripts to fail CI on an
unfinished gate; the pre-launch checklist
reference explains each item.
8. Failure modes
The gate every mutation route enforces — shown here with a live key:Honest limits
- Number inventory is fictional. Provisioned numbers come from the
NANP-reserved
+1 (555) 01XXrange and carryprovider: "sandbox"— they can send to and receive from other sandbox fixtures only. No carrier ever sees them. - Channels that still run live. Only SMS, MMS, WhatsApp, and Email
short-circuit in test mode. Voice, RCS, push, and fax still hit their
real stacks and bill normally even with a sandbox key — route those
tests at
+1 555numbers to avoid carrier fees, and expect no sandboxinboundsupport for them (the endpoint accepts only the three messaging channels above). - Sandbox POSTs write real rows into your sandbox tenant. Reset is the only cleanup — there is no per-route undo.
- Rate budget is shared. Console clicks on the Developer → Sandbox page and your scripts draw from the same 60 req/min write limit.
Related pages
- Sandbox overview — the concepts, activation signals, and constants this cookbook exercises
- Sandbox and test mode — the end-to-end walkthrough including magic-number sends and deterministic verify codes
- Sandbox dashboard walkthrough — the console equivalent of every recipe here
- Magic numbers — the 10 delivery scenarios in full
- Pre-launch checklist — the five-step gate, item by item
- Developer API playground — run these calls from the in-console request console instead of curl