> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.goautolane.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.goautolane.com/_mcp/server.

# Delivery status now reports the delivery lifecycle

The top-level `status` field on delivery responses now reports the
**delivery lifecycle** — the same vocabulary emitted by
`pickup_status.changed` webhooks — instead of the internal order state
machine. This resolves a long-standing inconsistency where the GET
endpoint could report `PENDING` while webhooks were progressing through
`ASSIGNED`, `EN_ROUTE_TO_STORE`, and beyond.

## What changed

* **`POST /dd/v1/deliveries`** now returns `status: "SCHEDULED"` for a
  newly created delivery (previously `"PENDING"`).
* **`GET /dd/v1/deliveries`** and
  **`GET /dd/v1/deliveries/{external_delivery_id}`** now return the
  delivery lifecycle status at the top level: `SCHEDULED`, `ASSIGNED`,
  `EN_ROUTE_TO_STORE`, `ARRIVED_AT_STORE`, `WAITING_FOR_LOAD`, `LOADED`,
  `EN_ROUTE_TO_CUSTOMER`, `ARRIVED_AT_CUSTOMER`, `COMPLETED`, `FAILED`,
  `CANCELLED`, or `EXPIRED`. The GET response and the webhook stream now
  always agree.
* **The list endpoint's `?status=` filter** accepts the same lifecycle
  values. The legacy order-status vocabulary (`PENDING`, `READY`,
  `ACCEPTED`, `dispatching`, `en_route`, `arriving`, `arrived`,
  `waiting_for_pickup`, `returning`) is no longer accepted and returns
  `400 VALIDATION_ERROR`.
* **`estimated_arrival`** in `pickup_status.changed` webhook payloads is
  now populated with the delivery ETA (estimated arrival at the
  customer, locked at quote time). Previously this field was always
  `null`.
* **Sandbox `vehicle_location`** is now populated: the synthetic vehicle
  records a location fix at every portal advance, so status-change
  payloads for subscribers of `pickup.vehicle_location.changed` carry a
  fresh position instead of `null`.

## Migration

If your integration reads the top-level `status` or filters the list
endpoint by status, switch to the lifecycle vocabulary:

| Before (order status)    | After (delivery lifecycle)                                  |
| ------------------------ | ----------------------------------------------------------- |
| `PENDING`                | `SCHEDULED`                                                 |
| `READY`                  | `SCHEDULED` (until dispatch) or the current dispatch state  |
| `ACCEPTED` … `returning` | The corresponding `ASSIGNED` … `ARRIVED_AT_CUSTOMER` states |
| `CANCELLED`              | `CANCELLED` (unchanged)                                     |
| `EXPIRED`                | `EXPIRED` (unchanged)                                       |

The nested `pickup.status` field is unchanged and now always matches the
top-level `status`; prefer reading the top-level field.