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.
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
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.
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. 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 the event’s live data, such as {"type":"call.ended","data":{"project_id":"PROJECT_ID","number":{"id":"VIRTUAL_NUMBER_ID","handle":"+12025550100"},"resource":{"call_id":"fixture-call","direction":"outbound","outcome":"answered","talk_seconds":42}}}. Your data is sent as given. These are caller-supplied fixtures, not a simulation of the phone network.
Simulated events use the live shapes. Message events carry data.message and data.conversation; the conversation’s link_code matches GET /v1/threads but the link opens nothing. Group events put the group under data.resource.group, and contact.updated puts the contact directly under data. The virtual number is an iMessage line, so SMS and MMS are not simulated.
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.