# Test in a sandbox

A live key acts as a real broker in a real brokerage, so a bug in your integration can change a real
book or reach a real client. A **sandbox** is a private brokerage with sample data that records
everything it would have sent, and sends none of it. Build there, then swap the key.

## Create a sandbox

An admin of your brokerage can make one.

1. Go to **Settings > Developer**.
2. Under **Sandboxes**, select **New sandbox**, give it a name, and select **Create sandbox**.
3. Copy the test key, the sign-in email, and the password. You will only see them once.

You can have three sandboxes at a time.

BrokerPlus fills a new sandbox with sample contacts, deals, and tasks within a few moments. Nothing
from your real brokerage is copied in. Sign in to the web app with the sandbox email and password to
watch what your integration does, as a broker would see it. An admin of your real brokerage can
reset that password in **Settings > Developer**.

## Sandbox keys

A sandbox key starts with `bp_test_`, and a live key with `bp_live_`. Otherwise they work the same,
in the same `Authorization` header.

The two never cross. A sandbox key only reaches its own sandbox, a live key cannot reach a sandbox,
and a key whose prefix does not match its brokerage gets `401`. Ids from your real brokerage do not
exist in a sandbox, so they return `404`.

## What a sandbox does instead of sending

Every flow runs as it would in production, up to the point where something would leave BrokerPlus.

| Action                             | In a sandbox                                                                 |
| ---------------------------------- | ---------------------------------------------------------------------------- |
| Email and text messages            | Recorded, and reported as sent.                                              |
| Credit reports                     | Recorded. Returns the Equifax test subject, not a real credit file.          |
| Lender submissions                 | Recorded. No lender gets the deal, and no decision comes back.               |
| Billing, phone numbers, and calls  | Refused with `403 SANDBOX_REFUSED`.                                          |

Every request that [reaches a client](/reaching-clients) runs in a sandbox too, up to the send,
which is recorded instead. Webhooks from a sandbox are delivered to your endpoint like live ones, which makes a
sandbox the right place to test your [webhook](/webhooks) receiver.

## See what it would have sent

`GET /v1/sandbox/outbox` lists every message and request the sandbox recorded, newest first. Only a
sandbox key can call it; a live key gets `403 SANDBOX_ONLY`.

```bash title="curl"
curl "https://api.mos.getbrokerplus.ca/v1/sandbox/outbox?channel=email" \
  -H "Authorization: Bearer $BROKERPLUS_TEST_KEY"
```

```json
{
  "success": true,
  "data": [
    {
      "object": "sandbox_outbox_entry",
      "id": "cmuy7q2k0001",
      "channel": "email",
      "adapter": "broker_email",
      "recipients": ["sam@example.com"],
      "subject": "Your mortgage documents",
      "body": "<p>Hello Sam,</p>",
      "deal_id": "cmuy7p9x0004",
      "created_at": "2026-10-07T14:02:11.000Z"
    }
  ],
  "pagination": { "page": 1, "page_size": 50, "total": 1, "total_pages": 1 }
}
```

Filter with `channel` (`email`, `sms`, `credit`, or `lender`). With `updated_since`, you get only
what was recorded at or after that time, oldest first.

## Expiry

A sandbox lasts 30 days from the last time its key was used, and each request pushes that date
out. After that, the key returns `401` and BrokerPlus deletes the sandbox and its data. To start
over with fresh sample data, delete the sandbox in **Settings > Developer** and make a new one.

## Before you go live

A sandbox is close to production, not identical. A lender package can need the full credit report
file, which the sample credit report does not have, so a sandbox can show a deal as not ready to
submit when a real one would be.

When everything works, create a live key and change only the key.
