> ## 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.

# 10-minute quickstart

> Copy, paste, and create your first simulated delivery.

This walkthrough creates a delivery in the sandbox. Nothing here dispatches a real rider or charges money.

You will make four requests:

1. Ask for a delivery quote.
2. Create a simulated delivery.
3. Move it to the `assigned` status.
4. Read its current status and event history.

<Tip>
  Run each command in a terminal. Lines beginning with `export` save a value only for that terminal window.
</Tip>

## 1. Copy your test key

In the developer portal, create an application and then create a **test** key. Copy the full key when it appears; it is shown only once.

Replace `paste_your_complete_test_key_here` below, then run both lines:

```bash theme={null}
export HAULSTOW_BASE_URL="https://sandbox.developer.haulstow.co/v1"
export HAULSTOW_API_KEY="hsg_test_key_paste_your_complete_test_key_here"
```

Your key must begin with `hsg_test_key_`. Keep the quotation marks.

## 2. Calculate a quote

This request asks, “What would a bike delivery between these two coordinates cost?” It does not create a delivery, so it does not need an idempotency key.

```bash theme={null}
curl --request POST "$HAULSTOW_BASE_URL/quotes" \
  --header "Authorization: Bearer $HAULSTOW_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "pickup": {"latitude": 5.6037, "longitude": -0.1870},
    "dropoff": {"latitude": 5.6698, "longitude": -0.1695},
    "vehicle_type": "bike"
  }'
```

You should receive a response shaped like this:

```json theme={null}
{
  "success": true,
  "statusCode": 200,
  "message": "Quote calculated",
  "data": {
    "environment": "test",
    "simulated": true,
    "vehicle_type": "bike",
    "currency": "GHS",
    "distance_km": 7.6,
    "distance_source": "sandbox_fixture",
    "fee": 40,
    "requires_custom_quote": false
  }
}
```

Your exact `distance_km` may differ slightly. A sandbox trip over 15 km returns `"requires_custom_quote": true` and `"fee": null`.

<Warning>
  If you receive `INVALID_API_KEY`, make sure you copied the entire key and included `Bearer ` before it. If you receive `ENVIRONMENT_MISMATCH`, you used a live key with the sandbox URL or a test key with the live URL.
</Warning>

## 3. Create a delivery

This example creates the recipient and address inside the delivery request. HaulStow returns reusable recipient and address IDs in the response.

The `Idempotency-Key` value identifies this one create action. If the command times out, run the **same command with the same key**. HaulStow will return the first result instead of creating a duplicate.

```bash theme={null}
curl --request POST "$HAULSTOW_BASE_URL/deliveries" \
  --header "Authorization: Bearer $HAULSTOW_API_KEY" \
  --header "Content-Type: application/json" \
  --header "Idempotency-Key: shop-order-1842-create-v1" \
  --data '{
    "external_id": "shop-order-1842",
    "recipient": {
      "name": "Ama Mensah",
      "phone_number": "+233245412312",
      "address": {
        "label": "Home",
        "address": "15 Independence Avenue, Accra",
        "latitude": 5.5600,
        "longitude": -0.2057,
        "municipality": "Accra Metropolitan",
        "delivery_notes": "Call when you arrive"
      }
    },
    "pickup": {
      "name": "Osu Store",
      "contact": "+233200000001",
      "address": "Oxford Street, Osu, Accra",
      "latitude": 5.5560,
      "longitude": -0.1820
    },
    "payment": {"type": "cod", "goods_value": 185},
    "vehicle_type": "bike"
  }'
```

The response contains a delivery ID beginning with `dlv_`:

```json theme={null}
{
  "success": true,
  "statusCode": 201,
  "message": "Delivery created",
  "data": {
    "id": "dlv_3f1a821cdb58498cbb52f4706545a089",
    "external_id": "shop-order-1842",
    "environment": "test",
    "simulated": true,
    "status": "booked",
    "recipient": {
      "id": "rcp_..."
    },
    "dropoff": {
      "id": "adr_..."
    }
  }
}
```

Copy the complete `data.id` value and save it in your terminal:

```bash theme={null}
export HAULSTOW_DELIVERY_ID="dlv_3f1a821cdb58498cbb52f4706545a089"
```

Replace the example ID with the one from your response.

## 4. Trigger a sandbox event

Real deliveries change status when HaulStow operations and riders do their work. In the sandbox, you trigger those changes yourself.

Move the delivery from `booked` to `assigned`:

```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: shop-order-1842-assigned-v1" \
  --data '{"status":"assigned"}'
```

The next valid states are:

```text theme={null}
booked -> assigned -> picked_up -> in_transit -> delivered
```

Move one step at a time. Skipping from `assigned` directly to `delivered` returns `SANDBOX_TRANSITION_INVALID`.

## 5. Check the delivery

Get the latest delivery snapshot:

```bash theme={null}
curl "$HAULSTOW_BASE_URL/deliveries/$HAULSTOW_DELIVERY_ID" \
  --header "Authorization: Bearer $HAULSTOW_API_KEY"
```

Get its complete public event history:

```bash theme={null}
curl "$HAULSTOW_BASE_URL/deliveries/$HAULSTOW_DELIVERY_ID/events" \
  --header "Authorization: Bearer $HAULSTOW_API_KEY"
```

If you configured a webhook endpoint, every accepted sandbox transition also queues a signed webhook. The payload and signature format are the same in live mode.

## You are ready for the next step

You now know the basic request flow. Next:

* Learn why retries need an [idempotency key](/idempotency).
* Learn how to get automatic updates with [webhooks](/webhooks).
* See how to create and reuse recipients in the [API reference](/reference).
* Use [common errors](/errors) if a command fails.
