<!-- https://missblue.dev/docs/sandbox -->

Getting started

# Test your integration in the sandbox

Use the same API URL with an `mb_sandbox_` key. Requests use a virtual number and isolated project fixtures. No paid number, real message delivery, or Mac connection is needed.

## 1. Create a sandbox key

Open your project’s Sandbox page and choose Create key → Sandbox. Save it as MISS\_BLUE\_SANDBOX\_KEY in your environment. The page also has a playground you can use before creating a key.

```bash
curl https://api.missblue.dev/v1/numbers \
  -H "Authorization: Bearer $MISS_BLUE_SANDBOX_KEY"
```

The returned number ID belongs to this project’s sandbox. Real number, message and attachment IDs cannot be used here.

## 2. Choose an outcome

```bash
curl -X POST https://api.missblue.dev/v1/messages \
  -H "Authorization: Bearer $MISS_BLUE_SANDBOX_KEY" \
  -H "Content-Type: application/json" \
  -H "X-Miss-Blue-Sandbox-Scenario: reply" \
  -d '{"number_id":"VIRTUAL_NUMBER_ID","recipient":"+12025550101","text":"Hello from my integration"}'
```

The recipient is only a fixture label. Nobody at that number receives a message. Simulator responses include `X-Miss-Blue-Sandbox: true`.

| Scenario | Result |
| --- | --- |
| sent | 201 · sent; waits for a receipt |
| delivered (default) | 201 · delivered; emits sent and delivered events |
| read | 201 · delivery and read receipts |
| reply | 201 · delivery plus an incoming message and message.received event |
| failed | 400 · failed fixture and message.failed event |
| offline | 201 · pending with queued: true |
| rate\_limited | 429 · Retry-After: 60; no message created |
| timeout | 504 · pending fixture; outcome unknown |

These are immediate simulations, including timeouts. To advance an existing pending or sent message, use Messages in the playground or POST `/v1/sandbox/messages/MESSAGE_ID/simulate` with `{"scenario":"reply","reply_text":"Thanks!"}`. Completed receipts cannot move backwards. Repeated replies create additional incoming messages.

## 3. Verify signed webhooks

Register a public HTTPS endpoint in the sandbox page, or use POST `/v1/projects/PROJECT_ID/webhooks` with your sandbox key. Its signing secret is returned once. Sandbox endpoints are separate from live endpoints and receive real HTTP requests containing simulated events.

```bash
curl -X POST https://api.missblue.dev/v1/projects/PROJECT_ID/webhooks \
  -H "Authorization: Bearer $MISS_BLUE_SANDBOX_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://your-app.com/webhooks/missblue","events":["message.received","message.delivered"]}'
```

Verify `Miss-Blue-Signature` using the [normal HMAC scheme](https://missblue.dev/docs/receiving-messages). The envelope includes `sandbox: true` and the request includes `X-Miss-Blue-Sandbox: true`. Return any 2xx status to acknowledge delivery. Failures retry through the durable queue; attempts and HTTP statuses are visible in the playground. Redirects, private destinations and ports other than 443 are refused.

A per-message `status_callback` is also supported and is unsigned, matching the live API. To test any documented webhook event with your own fixture data, POST `/v1/sandbox/events` with `{"type":"call.ended","data":{"call":{"id":"fixture-call"}}}`. These are caller-supplied fixtures, not a simulation of the phone network.

## Supported requests and limits

-   Identity, virtual numbers, sending and reading messages, threads, lookup, reactions, unsend, edit, typing and read receipts.
-   Contacts: save, remember, list, detail, update, delete and simulated sync. Groups: create, read, rename and edit participants.
-   Raw attachment uploads up to 1 MiB store metadata and a checksum. File content is discarded; media downloads and group photos are not simulated.
-   100 messages, 100 contacts, 20 attachments, 20 groups and 3 webhook endpoints per project. The latest 200 events are retained; older pending deliveries are discarded with their events.
-   JSON requests are limited to 64 KiB and total fixture storage to about 1.5 MB. Request-rate limits still apply.
-   Billing, real calls, agent operations and device configuration are unsupported. Supported routes with unsupported operations return 501; unknown routes may return 404. No unsupported request reaches a live handler.

Fixtures expire after seven days and reset on the next request. DELETE `/v1/sandbox` clears them immediately, including sandbox webhook endpoints. API keys stay active. Your team shares the project sandbox.

## Going live

Create a Live key, connect a real number and register a live webhook with its own signing secret. Use the real IDs returned by that key and remove the scenario header. Fixtures are not copied to live data. Legacy `mb_test_` keys still reach real traffic; only `mb_sandbox_` selects the simulator.

[Next Sending messages Connect a real number and send your first live message.](https://missblue.dev/docs/sending-messages)
