Skip to content

Driver API

Driver traffic goes to the Admin API (http://localhost:5001).

Staff login

Same as the picker: POST /v1/auth/login with email/password. Persist accessToken + refreshToken. Send Authorization: Bearer <accessToken> on every call. Refresh at POST /v1/auth/refresh with { "refreshToken" }.

Route the UI when results.user.roleKey === "driver".

Development seeds: driver1@test.com, driver2@test.com, password 123. Permissions: orders:read, orders:update. Branch-scoped if branchIds is set.

Workflow

ready --pickup--> out_for_delivery --deliver--> delivered
                         |
                         +--fail--> delivery_failed --retry--> out_for_delivery
                                              |
                                              +--return--> ready

Poll GET /v1/fulfillment/driver/orders. Queue statuses: ready, out_for_delivery, delivery_failed.

Endpoints

GET requires orders:read. POST requires orders:update.

MethodPathBodyPurpose
GET/v1/fulfillment/driver/ordersQueue cards
GET/v1/fulfillment/driver/orders/:orderIdFull order + delivery attempts
POST/v1/fulfillment/driver/orders/:orderId/pickupStart trip; status → out_for_delivery
POST/v1/fulfillment/driver/orders/:orderId/deliverSuccess; status → delivered
POST/v1/fulfillment/driver/orders/:orderId/fail{ reason, note? }Failed visit
POST/v1/fulfillment/driver/orders/:orderId/retryLeave the store again
POST/v1/fulfillment/driver/orders/:orderId/returnBag back to store; status → ready

Fail reasons

reasonUse when
customer_absentNobody at the door
refusedCustomer declined the order
wrong_addressAddress cannot be used
unreachablePhone / access failed
otherAnything else (note recommended)

note is optional, max 256 characters.

Pickup then deliver example

http
POST /v1/fulfillment/driver/orders/665f0c0c0c0c0c0c0c0c0c10/pickup
Authorization: Bearer <accessToken>
http
POST /v1/fulfillment/driver/orders/665f0c0c0c0c0c0c0c0c0c10/deliver
Authorization: Bearer <accessToken>

Fail example

http
POST /v1/fulfillment/driver/orders/665f0c0c0c0c0c0c0c0c0c10/fail
Content-Type: application/json

{ "reason": "customer_absent", "note": "No answer after 3 minutes" }

retry does not re-notify the customer. return puts the order back on the picker-ready shelf for a new trip.

Order delivery includes driver, pickedUpAt, optional deliveredAt, attempts[], and lastFailureReason.

GPS

The delivery schema allows location later. The current API does not accept live GPS pings.