Skip to main content
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, picked items, 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 (PATCH /v1/fleet/deliveries/{delivery_id}) to report a change on one delivery. The body is partial — include only the fields that changed.
1

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

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

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

Report what was picked

When your fleet picks the order in store, send pickedItems with every row picked so far, and items_pick_complete once the pick is done. See Reporting picked items.
5

Attach proof of delivery

At pickup or dropoff, include proofOfDelivery — image artifacts (photo or signature) or barcode scans — discriminated by type.
6

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.
A single update can carry any combination of the following fields: The endpoint returns the updated delivery object — the same shape you’d see nested under a job’s task in Get Job.

Bulk updates

When you have updates for many deliveries to flush at once, use 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.

Reporting picked items

When your fleet picks the order in store before delivering it, report what the picker found with pickedItems, and send the items_pick_complete status when the pick is finished. One request can carry both.
Picked items and items_pick_complete are turned on per organization. Ask your Nash contact to enable them. Until then, a request that carries either returns 403 with the error code DELIVERY_PICKING_NOT_ENABLED. In a bulk request, only that item fails.
pickedItems is the delivery’s whole picked list, not an addition to it. Each request replaces the rows Nash holds, so send every row picked so far. Sending the same list again changes nothing, which makes a retry safe. Nash sends the items_pick_update webhook event when the list changed. Each row is one outcome for an order line: A line answered by both the item ordered and a substitute is two rows that share requestedSku. This request finishes a pick where the order asked for two cartons of milk and a loaf of bread. The picker found one carton, replaced the other with two smaller ones from the order’s list, and found no bread:
Rules to keep in mind:
  • A list holds 1 to 200 rows and at most 64 KB as JSON.
  • Nash stores the rows as sent. It checks their shape, not whether they match the order’s lines.
  • items_pick_complete belongs before pickup_complete. Nash ignores it once the delivery is picked up.
  • A closed delivery ignores picked items, as it does every field except proof of delivery.
  • Nash stores substitutionType and substitutionSource, but the delivery object and webhook payloads don’t return them yet.

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 for the full list.
  • Simulate Delivery Status Transition — this endpoint (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.
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.

Lifecycle & validation

A typical happy path moves through:
The full set of status values you can send is: not_assigned_driver, assigned_driver, pickup_enroute, pickup_arrived, items_pick_complete, pickup_complete, dropoff_enroute, dropoff_arrived, dropoff_complete, failed, canceled_by_provider, return_in_progress, return_arrived, returned_to_store. A fleet that picks the order sends items_pick_complete between pickup_arrived and pickup_complete. See Reporting picked items. 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.
  • proofOfDelivery artifacts must be reachable URLs — a file:// reference is rejected. A delivery holds at most 50 photos and signatures and, counted apart from those, at most 200 barcode records across pickup, dropoff, and return; the same barcode recorded at pickup and again at dropoff is two records. Any of those problems fails the whole update rather than dropping the artifact quietly, so a rejected proof is something you find out about.

Next steps

Fleet overview

How the inbound Fleet API surface fits together.

Update Delivery

PATCH a single delivery’s state.

Bulk Update Deliveries

Flush updates for up to 100 deliveries at once.

Simulate Delivery Status Transition

Drive a sandbox delivery to a given status.