# Test with the sandbox

> A separate, free and unlimited environment, with a simulator to test your webhooks without a WhatsApp number.

Each application has a **sandbox** environment, strictly separate from production: its own keys (`pk_test_…`), businesses, numbers, webhooks and data.

| | Sandbox | Production |
|---|---|---|
| Keys | `pk_test_…` | `pk_live_…` |
| Quota and business count limits | None | Those of your plan |
| Bref Point Inbox billing | None | Depends on your plan |
| Simulator | Yes | **Rejected** (`403 sandbox_only`) |

<Callout type="note" title="What about Meta in the sandbox?">
An account connected in the sandbox is a Meta test account: the messages you **send** really do go to Meta (and to the recipients this test account allows). The **simulator**, on the other hand, never contacts Meta: it builds the events locally.
</Callout>

## Simulate a received message

Ideal for testing your receiving flow end to end: the message is stored, the 24-hour window opens for this sender, and your `message.received` webhook fires exactly as in production (the data carries `"simulated": true`).

<ApiExample method="POST" path="/sandbox/simulate/inbound-message" />

## Advance a message's status

After a send (`POST /messages`), move the message along as Meta would:

<ApiExample method="POST" path="/sandbox/simulate/message-status" />

The same rules as in production apply: a status **never goes backward**, and a `failed` doesn't replace a message that is already `read`. A transition with no effect simply responds with the current state.

## A complete scenario

1. Connect a number in the sandbox and declare a webhook on `*` ([Quickstart](/docs/quickstart)).
2. `POST /sandbox/simulate/inbound-message`: your server receives `message.received`.
3. Reply with `POST /messages` (free-form message, the window is open).
4. `POST /sandbox/simulate/message-status` with `delivered`, then `read`: you receive the corresponding events.
5. Cause a failure on your side (a `500` response) and watch the automatic retries in `GET /webhook-deliveries`.
6. When everything works, create a production key and reuse the same calls.
