Picker API
Picker traffic goes to the Admin API (http://localhost:5001), not the Public API.
Staff login
| Method | Path | Body |
|---|---|---|
POST | /v1/auth/login | { email, password } |
GET | /v1/auth/me | Current user + roleKey |
POST | /v1/auth/refresh | { "refreshToken" } |
POST | /v1/auth/logout | Bearer access token |
POST /v1/auth/login
Content-Type: application/json
{ "email": "picker1@test.com", "password": "123" }On success, JSON includes user, accessToken, refreshToken, tokenType, expiresIn (15 minutes). Persist the pair in SecureStore. Send Authorization: Bearer <accessToken> on every fulfillment call. On 401, refresh with { "refreshToken" }, store the new pair, retry once. Route the UI by results.user.roleKey === "picker".
Development seeds: picker1@test.com, picker2@test.com, password 123. The role grants orders:read and orders:update.
If the user has branchIds, the queue is limited to those branches.
Workflow
confirmed --start--> picking --scan / unavailable / substitute--> readyPoll GET /v1/fulfillment/picker/orders (no WebSocket).
Endpoints
All paths are on the Admin API. GET requires orders:read. POST requires orders:update.
| Method | Path | Body | Purpose |
|---|---|---|---|
GET | /v1/fulfillment/picker/orders | — | Queue cards |
GET | /v1/fulfillment/picker/orders/:orderId | — | Full order + picking state |
POST | /v1/fulfillment/picker/orders/:orderId/start | — | Claim; status → picking |
POST | /v1/fulfillment/picker/orders/:orderId/scan | { barcode } | Match SKU or line key |
POST | /v1/fulfillment/picker/orders/:orderId/unavailable | { lineKey } | Item not on shelf |
POST | /v1/fulfillment/picker/orders/:orderId/substitute | { lineKey, productId, variantId? } | Swap product |
POST | /v1/fulfillment/picker/orders/:orderId/ready | — | Finish; all lines must be handled |
Queue card
results.data[] includes _id, orderNumber, status, fulfillmentMode, branch, lineCount, express, optional etaMinutes / deliverySlot, timestamps.
Scan example
POST /v1/fulfillment/picker/orders/665f0c0c0c0c0c0c0c0c0c10/scan
Content-Type: application/json
Authorization: Bearer <accessToken>
{ "barcode": "6281000000001" }Barcode matching uses the variant sku or the order line key.
Ready
POST .../ready fails until every line is scanned, substituted, or marked unavailable. Success applies stock adjustments and sets status to ready.
Action responses typically wrap { message } with statusMessage: "UPDATED". Re-fetch the order after each POST.