Skip to main content

EXPRESS

On-demand last-mile delivery. Dash allocates the nearest available driver, the package is collected at pickup, and delivered in a single leg. The bulk of the API surface is built for this flow.

Deprecation — legacy shared endpoints. The shared /v1/deliveries/... endpoints are deprecated (21 May 2026) and will be obsoleted on 21 November 2026. EXPRESS now uses dedicated /express/v1/... paths. Migrate before the obsoletion date.

When to use EXPRESS

Use EXPRESS when:

  • You need same-hour or same-day fulfilment.
  • The package is collected from a known pickup point (a restaurant, an outlet, a shop) and delivered to a single recipient.
  • No warehouse verification is required.

Service types

INSTANT
On-demand allocation to the nearest available driver. Typical pickup window: a few minutes.
SAME_DAY
Scheduled pickup within a same-day window. Use the schedule.pickupTimeFrom / pickupTimeTo fields. Max 3 days ahead.

State machine

QUEUEING(if scheduled)ALLOCATINGPENDING_PICKUPPICKING_UPPENDING_DELIVERYIN_DELIVERYCOMPLETEDreassignmentCANCELLEDprovider · before pickupFAILED_PICKUPFAILED_DELIVERYPENDING_RETURNIN_RETURNRETURNEDreturn legFAILED_IN_RETURNON_HOLDre-queued by Dash Opshanded back at the pitstopDISPOSEDLifecycleCompletedCancelledFailed(green, orange, red = terminal)

Transitions

create → ALLOCATING / QUEUEING
On creation, an unscheduled delivery starts in ALLOCATING. A scheduled one starts in QUEUEING and moves to ALLOCATING when its pickup window opens.
ALLOCATING → PENDING_PICKUP
Driver accepts. The courier block becomes available — name, phone, vehiclePlateNumber, profileImageUrl.
PENDING_PICKUP → PICKING_UP
Driver is moving toward pickup. Dash may still re-assign — a fresh webhook fires with updated courier.
PICKING_UP → PENDING_DELIVERY
Driver captured PICKUP_PROOF. Package is in hand — pickupAt is set and cancellation is now closed.
PENDING_DELIVERY → IN_DELIVERY
Driver is en route to drop. trackingURL is now valid.
IN_DELIVERY → COMPLETED
Driver captured DELIVERY_PROOF at the destination. recipient.actualRecipientName populated.
… → CANCELLED
Provider DELETE is allowed any time before pickup — ALLOCATING, PENDING_PICKUP, or PICKING_UP. Closed once the package is picked up (PENDING_DELIVERY). Terminal.
ALLOCATING / PENDING_PICKUP / PICKING_UP → FAILED_PICKUP
Package could not be collected — no driver available, sender unavailable, package not ready, address not found. pickupAt stays null and there is no return leg. reason and an EB reasonCode are populated. Terminal.
IN_DELIVERY → FAILED_DELIVERY
Drop could not complete — recipient unavailable, COD refused, SLA exceeded. reason and an EC reasonCode are populated. The package is in hand, so this is the only failure that can enter the return flow (PENDING_RETURN → IN_RETURN → RETURNED, or FAILED_IN_RETURN if the hand-back fails). Terminal otherwise.
IN_RETURN → FAILED_IN_RETURN
The return leg itself failed — nobody reachable at the return address, the location was closed, an operational issue, not enough time left in the shift, weather. reason and an ED reasonCode are populated and FAILED_RETURN_PROOF is captured; the driver still holds the package, so courier stays populated. Not terminal — Dash Ops takes the package over from here.
FAILED_IN_RETURN → ON_HOLD
Ops parked the package at a pitstop and released the driver from the job. Not terminal — from here ops re-attempts the return (fresh PENDING_RETURN), hands it back at the pitstop (RETURNED), or writes it off (DISPOSED).
ON_HOLD / FAILED_* → DISPOSED
Package written off instead of returned — reachable from a hold, or straight from a failure: FAILED_DELIVERY, and also FAILED_PICKUP, where nothing was collected. Terminal.

Reassignment loops. The Dash dispatcher can move a delivery back to PENDING_PICKUP from PICKING_UP, PENDING_DELIVERY, or IN_DELIVERY when a driver becomes unavailable. Each reassignment fires a fresh webhook with the updated courier block — always treat the most recent value as authoritative.

EXPRESS-only fields and webhook statuses

These are emitted only when serviceCategory: "EXPRESS":

  • Statuses: ALLOCATING, PENDING_PICKUP, ARRIVED_AT_PICKUP_POINT, ARRIVED_AT_DESTINATION
  • Statuses: FAILED_PICKUP / FAILED_DELIVERY — the v2 leg-split failure statuses. LOGISTIC still emits a single FAILED.
  • Webhook field: trackingURL (present from PENDING_PICKUP onward)
  • POD media: PICKUP_PROOF is captured by the driver (LOGISTIC skips this)

Endpoints

EXPRESS uses dedicated /express/v1/... paths. The legacy shared /v1/deliveries/... paths still work but are deprecated (21 May 2026) and will be obsoleted on 21 November 2026 — migrate before then.

POST /express/v1/deliveries/quotes
Pre-flight quote. See Get delivery quote.
POST /express/v1/deliveries
The EXPRESS-specific create endpoint. See Create delivery.
GET /express/v1/deliveries/{deliveryID}
Read current state. See Get delivery details.
DELETE /express/v1/deliveries/{deliveryID}
Cancel any time before pickup — ALLOCATING / PENDING_PICKUP / PICKING_UP. See Cancel delivery.
POST /express/v1/deliveries/{deliveryID}/additional-notifications
Notify the driver. See Notify driver.

Gotchas

  • Driver re-assignment can happen on PENDING_PICKUP, PICKING_UP, PENDING_DELIVERY, or IN_DELIVERY. A re-assignment fires a fresh webhook with an updated courier block — name, phone, vehiclePlateNumber, and profileImageUrl all change together. Keep the most recent values.
  • Cancellation eligibility runs through PICKING_UP — you can cancel any time before the package is picked up (ALLOCATING, PENDING_PICKUP, PICKING_UP). Once the driver collects the package (PENDING_DELIVERY), the only terminal states are COMPLETED, FAILED_DELIVERY, or RETURNED.
  • trackingURL only exists on EXPRESS deliveries and only from PENDING_PICKUP onward.