> ## Documentation Index
> Fetch the complete documentation index at: https://docs.orbit.devotel.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Developer Sandbox console

> Work the Developer → Sandbox console end to end — mint test keys, send stubbed samples with scoped channels and rate caps, replay fixtures (DLR stubs, simulated callbacks), and convert to production keys.

# Developer Sandbox console

The **Developer → Sandbox** page in the dashboard is the console for your
sandbox workforce: where you mint test keys, scope channels, cap rate, run
isolated sends, replay test fixtures, and promote to production. Access is
restricted to the owner, admin, and developer roles — the page hides for
viewer roles.

This guide is console-first: the [sandbox overview](/sandbox/overview)
covers the activation model (the three sandbox signals) in depth, the
[dashboard walkthrough](/guides/sandbox-dashboard-walkthrough) narrates
each card in click order, and the [test-mode reference](/guides/sandbox-test-mode)
is the API-side authority. Here you get one storyline — from first key to
go-live — split by what each key tier is for.

## 1. What the Sandbox console is for

Use it to isolate experimentation from your production wallet and from the
people in your team.

* **Keep prod credentials untouched.** `dv_test_sk_*` keys are separate
  from your live `dv_live_sk_*` keys. Hand them to developers and CI jobs
  without worrying they could burn your production balance or deliver real
  traffic.
* **Persona-separate test keys.** Grant one test key to a CI harness, one
  to a local environment, one to a partner — the work is attributable and
  revocable per key, not per team member.
* **Never burn a conversation with a real recipient.** The stubbed
  channels below short-circuit before reaching a carrier; that is the
  point of the console, and the [provider stub-status table](#3-scoped-channels-and-rate-caps)
  flags the few channels that still bypass the stub and bill.

## 2. Get a sandbox key from the dashboard

Open **Developer → Sandbox** and find the **Test-mode API keys** card.

* If the card lists a `dv_test_sk_*` key already, copy it — nothing more
  to do.
* If the card is empty, click **Mint a test key**. The button jumps to
  **Settings → API Keys** with the creation dialog open; pick the **Test**
  type so the prefix lands as `dv_test_sk_`.

The page lists the test keys you already hold and flags each as active or
inactive. Mint as many as you like and label them: `ci-smoke`, `local-dev`,
`partner-sandbox`. Each one is independently revocable, which is what makes
them persona-separate in practice. The sandbox-to-production promotion
(section 7) expects you to already have one.

## 3. Scoped channels and rate caps

The **Provider test-mode status** card at the bottom of the page shows
which channels **Honour** the test-mode stub and which **Bypass** it. Read
the stub status before you send — a stubbed channel costs nothing, a
bypassed one behaves like live.

| Channel | Stub in test mode | Effect |
| - | - | - |
| SMS | Honoured | Stubbed end to end; no carrier submit, no billing |
| MMS | Honoured | Stubbed; the media URL is validated but never uploaded |
| WhatsApp | Honoured | Stubbed at the provider; template sends also short-circuit |
| Email | Honoured | Stubbed at the provider; no real send |
| Voice | Bypass | Live voice stack; minutes are billed — use a `+1 555` test number |
| RCS | Bypass | Dispatches to the real provider sandbox |
| Push | Bypass | Real deliveries; use a developer device |
| Fax | Bypass | Hits the live carrier regardless |

Rate caps are also part of the scope. Every sandbox mutation — reset,
provision-numbers, spawn-fixture-contacts, and Virtual Phone injection —
sits under the authenticated-write limit of **60 requests per minute per
organization**. A script that loops reset-then-provision in a tight retry
will see `429`; respect `Retry-After` and stay under the cap. The limit is
wide enough for a CI job, narrow enough that a runaway loop can't drain the
spec.

## 4. Send test messages without burn

With test mode toggled on (top of the page, mirrored from the topbar
Test/Live switch) you exercise the send path against the stubbed channels
and against **magic numbers** — deterministic fictional recipients whose
trailing digit selects the delivery scenario (`1` submitted only, `2`
delivered, `3` undelivered, and so on through the 10-state catalog on
[magic numbers](/sandbox/magic-numbers)).

The page's **Magic numbers** card renders the catalog inline, so you pick a
recipient by trailing digit and read the expected status, DLR latency, and
carrier-rewrite footer without leaving the console. The fixtures you seed
next (section 5) are pre-pinned to these recipients, so a running
conversation is one click away.

Sample shapes — SMS, email, and voice each have a send surface, and in the
stubbed channels the envelope comes back `cost_usd_cents: 0`:

```bash theme={null}
curl -X POST https://api.orbit.devotel.io/api/v1/messages/sms \
  -H "X-API-Key: dv_test_sk_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "to": "+15005550002",
    "from": "+15550142",
    "body": "Sandbox hello — trailing 2 simulates delivered"
  }'
```

```json theme={null}
{
  "data": { "status": "test_sent" },
  "meta": { "request_id": "req_sms_001", "test_mode": true, "timestamp": "2026-09-15T12:00:00Z" }
}
```

On a stubbed channel the send terminates locally at `test_sent`, so the
response marker `meta.test_mode: true` is your guarantee you didn't touch
a live upstream. A live key hitting the same shape returns the marker
absent and bills.

## 5. Test fixtures: DLR stubs and webhook replay

Three fixture routes live on this page. Use them through the page's
**Sandbox controls** card, or through the API directly — they are the same
calls.

* **DLR stubs via magic numbers.** `GET /sandbox/numbers` returns the
  10-state delivery-scenario catalog. Send to a magic recipient and the
  trailing digit picks the receipt shape — delivered in \~50 ms on a `2`
  recipient, no DLR on a `1` recipient, carrier-rewrite footer on the
  scenarios that carry one. That is the deliverability fixture.
* **Webhook replay via the sandbox webhook URL.** The **Sandbox webhook
  URL** card stores an org-level `https://` destination the sandbox-events
  worker POSTs simulated delivery-receipt and call-status callbacks to.
  Set it (or update it) here and your integration sees the same webhook
  shape production delivers — replayable on demand, and disabled when the
  field is blank.
* **Fixture contacts and inbound injection.** **Provision test numbers**
  mints deterministic `+1 (555) 01XX` fictional numbers, and **Spawn
  fixture contacts** seeds deterministic contacts pinned to magic-number
  recipients — so a reset-then-provision run sees the same address
  book. The **Virtual phone** card then simulates an inbound SMS / MMS /
  WhatsApp reply from a chosen sender into your inbox, which is how you
  exercise auto-responders and keyword handling without a real handset.

Reset wipes the fixture set without touching keys, webhook settings, or
org configuration — see the
[dashboard walkthrough](/guides/sandbox-dashboard-walkthrough) for the
exact reset semantics.

## 6. Convert sandbox keys to production

The promotion is a two-step key swap, not a rewrite:

1. **Read the pre-launch checklist.** The **Pre-launch checklist** card on
   this page tracks a five-step gate — sandbox workspace ready, live
   workspace ready, test API key minted, integration exercises the sandbox,
   IP allowlist configured. It reads `readyForLaunch: true` only when all
   five complete. The gate is shared: the same evaluation backs the
   checklist view, so a pending row is the same pending row anywhere you
   read it.
2. **Mint a live key and swap your config.** Under **Settings → API Keys**
   mint a **Live** key (`dv_live_sk_`). Update the environment variable
   your integration reads. The request shapes carry over verbatim — only
   the credential changes.

The [go-live checklist](/guides/go-live-checklist) guide walks the human
sign-off; the checklist card on this page reports machine readiness. Use
both before launch.

## 7. How this console guide differs from the top-level sandbox folder

The [top-level sandbox section](/sandbox/overview) and this guide are both
live references, but they point at different audiences:

* **This guide** is the operator path — the **Developer → Sandbox**
  console, the console-to-API mapping for every card, and the go-live
  gate you run before you hand off to a production integration. Start
  here while you are on the dashboard.
* **The top-level sandbox section** is the depth reference — the three
  activation signals, the `/sandbox/*` route constants, and the reset and
  promotion semantics rounded out with curl scripts for every endpoint.
  Jump there when the console guide can't tell you a constant or an
  activation rule.

Both cross-link; read either as the entry point.

## Related pages

* [Sandbox overview](/sandbox/overview) — the activation signals, route
  constants, and reset semantics in depth
* [Operate the Developer → Sandbox dashboard](/guides/sandbox-dashboard-walkthrough)
  — a card-by-card click walkthrough of this same page
* [Sandbox and test mode](/guides/sandbox-test-mode) — the API-side
  authority on the `X-Test-Mode` header and key-prefix routing
* [Magic numbers](/sandbox/magic-numbers) — the 10-state scenario catalog
  the console's fixture recipients key off
* [Pre-launch checklist](/sandbox/pre-launch-checklist) — the five-step
  go-live gate this page renders
* [Go-live checklist](/guides/go-live-checklist) — the human sign-off
  walkthrough after the machine gate reports ready
