Skip to main content
The Fleet API is the inbound surface a fleet uses to manage its drivers and report state on deliveries Nash has dispatched to it: courier location, status transitions, proof of delivery, picked items, courier identity, ETAs, and notes. Use it whether you’re a merchant operating your own couriers or a third-party fleet receiving Nash demand. The contract is the same in both cases: Nash dispatches a job (delivery) to your organization, you fulfill it, and you PATCH updates back as the delivery progresses.

Manage your drivers

Use Upsert Driver (PUT /v1/fleet/drivers/upsert) to create or update a driver in your internal fleet. Your externalIdentifier is the upsert key: send the same value again to update that driver, and inspect created in the response to tell whether Nash created a new record. Every request must include phoneNumber as an international number with a leading country code. Nash stores it in E.164 form, links the driver to a Nash user with your organization’s driver role, and provisions SMS sign-in for the Driver App. The linked driver also appears in your internal-driver list in the Portal. You can include email to add email sign-in too. Creating a driver through this endpoint does not send a welcome message. Keep these identity rules in mind:
  • A driver’s stored phone number cannot be changed through this endpoint.
  • A phone number already linked to another driver in your organization cannot be reused with a different externalIdentifier, even when that driver is disabled.
  • A phone number belonging to an active user outside your organization is rejected.
  • Omitting, clearing, or sending a blank email leaves the existing email unchanged.
There is no separate delete call. To make a driver unavailable, upsert the driver with isShiftActive: false; to disable the driver, use enabled: false.

Manage your driver groups

A driver group is a named set of your drivers that dispatch can target. If your roster already lives in a workforce or HR system, three endpoints keep the groups in Nash matched to it, so a change of depot or team doesn’t wait for someone to edit a list in the Portal. A group has two identifiers. externalIdentifier is yours and is the upsert key. firstVersionContractId is Nash’s, stays the same however often the group is edited, and is what the read endpoints and Upsert Driver take. There are two ways to change who is in a group, and they suit different sources of truth:
  • You hold the whole roster. Send driverIds on Upsert Driver Group. It replaces the group’s members with the list you send; [] removes everyone, and leaving the field out changes nothing.
  • You hear about one driver at a time. Send addFirstVersionContractIds or removeFirstVersionContractIds on Upsert Driver. The driver’s other memberships are kept. These two can’t be combined with firstVersionContractIds, which replaces all of a driver’s memberships.
A new group needs a displayName and starts active. There is no delete call: upsert with isActive: false to disable a group. A disabled group can lose members but can’t gain new ones.
The response is the group with its drivers and a created flag that says whether the call created it. Send the same externalIdentifier again with driverIds, your drivers’ Nash IDs, to set its roster.

Report delivery state

When updates start

Each dispatch event Nash sends carries a deliveryId. That’s the identifier you use on every update for that delivery’s lifetime. Updates only land on deliveries owned by your organization; anything else returns not-found.

Two endpoints for delivery state

Both accept partial bodies — only the fields you want to change need to be present.

Lifecycle

A typical happy path moves through:
Terminal failures use failed or canceled_by_provider, paired with a structured failure.code (e.g. customer_unavailable, address_not_found, no_capacity). Returns flow through return_in_progress → return_arrived → returned_to_store. Sending the same status twice is a no-op, so it’s safe to retry.

What you can include in a single call

A single update can carry any combination of:
  • status — lifecycle transition.
  • coordinates — { latitude, longitude }. Append-only; safe to send on every tick.
  • courier — name, phone, vehicle, profile image. Send on first assignment, or any subset on a mid-flight swap.
  • proofOfDelivery — image artifacts (photo / signature at pickup or dropoff) or barcode scans.
  • failure — structured { code, reason } for failed / canceled_by_provider.
  • pickupEta / dropoffEta — provider-supplied ETAs.
  • pickupNote / dropoffNote — free text the courier captured.
  • parkingLocation / returnParkingLocation — where the courier parked at the stop or when returning the package.
  • externalDeliveryId — your own identifier for this delivery, for cross-system reconciliation.

Validation

  • At least one mutating field is required per update — empty bodies return 422.
  • coordinates.latitude must be in [-90, 90], longitude in [-180, 180].
  • Wire format is camelCase; snake_case is also accepted.

Response shape

Both endpoints return the same delivery object you’d see nested under a job’s task in GET /v1/jobs/{id}. The bulk response wraps each item with a per-item success flag and either the updated delivery or a structured error.

Next steps

Report delivery state

Walk through reporting status, location, and proof of delivery.

Upsert a driver

Create or update a driver and provision their sign-in identity.

Upsert a driver group

Create a group or replace its roster from your own system.

Update a delivery

PATCH a single delivery as it progresses.

Bulk update deliveries

Flush updates for up to 100 deliveries at once.