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

# Report delivery state

> How a fleet reports status, location, proof of delivery, and ETAs back to Nash as a job (delivery) progresses — for single and bulk updates, and how to test transitions with Fleet simulators.

When Nash dispatches a job (delivery) to your organization, the Fleet API is how you report state back as the courier works through it — status transitions, courier location, proof of delivery, courier identity, ETAs, and notes. This guide walks through reporting state for a single delivery, flushing many updates at once, testing transitions in sandbox, and the lifecycle and validation rules that apply.

Every dispatch event Nash sends carries a `deliveryId`. That identifier is what you use on every update for that delivery's lifetime. Updates only land on deliveries owned by your organization — anything else returns not-found.

## Reporting state for a single delivery

Use [Update Delivery](/api-reference/fleet/update-delivery) (`PATCH /v1/fleet/deliveries/{delivery_id}`) to report a change on one delivery. The body is partial — include only the fields that changed.

<Steps>
  <Step title="Receive the dispatch and capture the deliveryId">
    When Nash dispatches the job (delivery) to you, store the `deliveryId` it carries. You'll send it on every subsequent update.
  </Step>

  <Step title="Report the first assignment">
    On assignment, send the `courier` object (name, phone, vehicle, and profile image as available) and a status such as `assigned_driver`. You can include `coordinates` and an ETA in the same call.
  </Step>

  <Step title="Send progress updates as the delivery moves">
    As the courier advances, `PATCH` each transition — `pickup_enroute`, `pickup_arrived`, `pickup_complete`, and so on. `coordinates` are append-only and safe to send on every location tick, alongside `pickupEta` / `dropoffEta` and any `pickupNote` / `dropoffNote`.
  </Step>

  <Step title="Attach proof of delivery">
    At pickup or dropoff, include `proofOfDelivery` — image artifacts (photo or signature) or barcode scans — discriminated by type.
  </Step>

  <Step title="Close out the delivery">
    Send `dropoff_complete` on success. For a terminal failure, send `failed` or `canceled_by_provider` together with a structured `failure` object. Returns flow through `return_in_progress → return_arrived → returned_to_store`.
  </Step>
</Steps>

A single update can carry any combination of the following fields:

| Field                                       | What it carries                                                                            |
| ------------------------------------------- | ------------------------------------------------------------------------------------------ |
| `status`                                    | A lifecycle transition (see [Lifecycle & validation](#lifecycle--validation)).             |
| `coordinates`                               | `{ latitude, longitude }` for the courier's current position. Append-only; safe to resend. |
| `courier`                                   | Courier identity and vehicle — name, phone, vehicle, profile image.                        |
| `proofOfDelivery`                           | Image (photo or signature) or barcode artifacts captured at a stop.                        |
| `failure`                                   | Structured `{ code, reason }` when the delivery enters `failed` or `canceled_by_provider`. |
| `pickupEta` / `dropoffEta`                  | Provider-supplied ETAs, ISO 8601.                                                          |
| `pickupNote` / `dropoffNote`                | Free-text notes the courier captured at a stop.                                            |
| `parkingLocation` / `returnParkingLocation` | Where the courier parked at the stop or when returning the package.                        |
| `externalDeliveryId`                        | Your own identifier for the delivery, for cross-system reconciliation.                     |

The endpoint returns the updated delivery object — the same shape you'd see nested under a job's task in [Get Job](/api-reference/job/get-job).

## Bulk updates

When you have updates for many deliveries to flush at once, use [Bulk Update Deliveries](/api-reference/fleet/bulk-update-deliveries) (`PATCH /v1/fleet/deliveries`). Send a `deliveries` array of up to 100 items, where each item is the same partial update you'd send to the single endpoint, keyed by its `deliveryId`.

The response returns a `results` array with one entry per request item, in order. Each result carries:

* `deliveryId` — the Nash delivery id.
* `success` — whether that item's update was applied.
* `delivery` — the updated delivery, on success.
* `errorCode` / `errorMessage` — failure detail, when `success` is `false`.

Per-item failures don't affect the rest of the batch, so a single bad item won't roll back the others. Inspect each result's `success` flag rather than relying on the overall HTTP status.

## Testing with Fleet simulators

In sandbox you can exercise your integration without a real courier. Two complementary tools:

* **fleet simulators** — mock fleets that emulate real-world scenarios. `FleetSimulator` cycles a job through statuses from driver-not-assigned up to dropoff-complete, `FleetSimulatorFast` does the same on a shorter interval, and `FailingFleetSimulator` sends a failed status. Simulators start the job based on its scheduled pickup time. See [Environments](/reference/environments) for the full list.
* **Simulate Delivery Status Transition** — [this endpoint](/api-reference/fleet-simulator/simulate-delivery-status-transition) (`POST /v1/deliveries/{delivery_id}/simulate`) advances a delivery to a specific status on demand, so you can drive your handlers through each state deliberately.

<Note>
  The simulate endpoint is available in dev and sandbox only, and only for deliveries dispatched to the Nash sandbox test provider. The behavior of fleets and fleet simulators is not an indication of how real fleets behave in production.
</Note>

## Lifecycle & validation

A typical happy path moves through:

```
pickup_enroute → pickup_arrived → pickup_complete →
dropoff_enroute → dropoff_arrived → dropoff_complete
```

The full set of status values you can send is:

`not_assigned_driver`, `assigned_driver`, `pickup_enroute`, `pickup_arrived`, `pickup_complete`, `dropoff_enroute`, `dropoff_arrived`, `dropoff_complete`, `failed`, `canceled_by_provider`, `return_in_progress`, `return_arrived`, `returned_to_store`.

Terminal failures use `failed` or `canceled_by_provider`, paired with a structured `failure.code`. Valid codes are `customer_unavailable`, `address_not_found`, `out_of_service_area`, `damage_in_transit`, `item_unavailable`, `age_verification_failed`, `no_capacity`, and `other`, with an optional free-text `reason`.

Validation rules to keep in mind:

* **At least one mutating field is required** per update — empty bodies return `422`.
* `coordinates.latitude` must be in `[-90, 90]` and `coordinates.longitude` in `[-180, 180]`.
* Wire format is camelCase; snake\_case is also accepted.
* Sending the same status twice is a no-op, so updates are safe to retry.

## Next steps

<CardGroup cols={2}>
  <Card title="Fleet overview" icon="truck-ramp-box" href="/fleet/overview">
    How the inbound Fleet API surface fits together.
  </Card>

  <Card title="Update Delivery" icon="pen-to-square" href="/api-reference/fleet/update-delivery">
    PATCH a single delivery's state.
  </Card>

  <Card title="Bulk Update Deliveries" icon="layer-group" href="/api-reference/fleet/bulk-update-deliveries">
    Flush updates for up to 100 deliveries at once.
  </Card>

  <Card title="Simulate Delivery Status Transition" icon="flask" href="/api-reference/fleet-simulator/simulate-delivery-status-transition">
    Drive a sandbox delivery to a given status.
  </Card>
</CardGroup>
