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

# Sandbox

> Safely practise the complete delivery flow with simulated data.

The sandbox is a safe practice environment. Use it while building and testing your integration.

```text theme={null}
Base URL: https://sandbox.developer.haulstow.co/v1
Key type: hsg_test_key_...
```

Sandbox and live data are completely separate. A recipient or delivery created in the sandbox does not exist in live mode. Sandbox responses make this visible:

```json theme={null}
{
  "environment": "test",
  "simulated": true,
  "tracking_url": null
}
```

## What the sandbox does not do

It does not:

* dispatch a real rider;
* send SMS, email, or push notifications to a recipient;
* charge or collect money;
* create invoices or accounting entries;
* reserve stock;
* change a live order;
* provide a live tracking link.

You can safely use example names, numbers, and addresses that meet validation rules. Avoid copying real customer data into a test environment unless you need it and are permitted to do so.

## Deterministic quotes

Sandbox prices are fixed test values based on straight-line distance. They are designed to make tests predictable, not to forecast the exact price of a future live delivery.

| Distance               |         Bike |      Minivan |
| ---------------------- | -----------: | -----------: |
| Up to 5 km             |       GHS 20 |       GHS 50 |
| Over 5 km, up to 15 km |       GHS 40 |       GHS 90 |
| Over 15 km             | Manual quote | Manual quote |

A trip over 15 km returns:

```json theme={null}
{
  "fee": null,
  "requires_custom_quote": true
}
```

## Simulate status changes

When you create a sandbox delivery, it starts at `booked`. In real life, riders and operations move the status forward. In the sandbox, call the transition helper yourself.

```bash theme={null}
curl --request POST "$HAULSTOW_BASE_URL/test-helpers/deliveries/$HAULSTOW_DELIVERY_ID/transition" \
  --header "Authorization: Bearer $HAULSTOW_API_KEY" \
  --header "Content-Type: application/json" \
  --header "Idempotency-Key: order-1842-assigned" \
  --data '{"status":"assigned"}'
```

The allowed order is:

```text theme={null}
booked -> assigned -> picked_up -> in_transit -> delivered
   |          |                         |
   +----------+-> cancelled             +-> failed
```

`booked` and `assigned` may also move to `cancelled`. `in_transit` may move to `failed`.

Each call moves exactly one step. For example, these are invalid:

* `booked` directly to `delivered`;
* `delivered` back to `in_transit`;
* any transition after a terminal state.

An invalid change returns `409 SANDBOX_TRANSITION_INVALID`.

Each accepted transition creates the same versioned event and signed webhook shape used in live mode. That makes the sandbox suitable for testing deduplication, ordering, signature verification, and terminal-state handling.

## Moving to live mode

When your sandbox flow works:

1. Create a separate live key beginning with `hsg_live_key_`.
2. Change the base URL to `https://developer.haulstow.co/v1`.
3. Keep your request JSON and response parsing the same.
4. Remove any calls to `/test-helpers/...`; that route exists only on the sandbox host.
5. Start with a controlled real delivery and monitor its webhook or polling flow.

Never make your code automatically fall back from sandbox to live or from live to sandbox.
