Skip to content

Picker API

Picker traffic goes to the Admin API (http://localhost:5001), not the Public API.

Staff login

MethodPathBody
POST/v1/auth/login{ email, password }
GET/v1/auth/meCurrent user + roleKey
POST/v1/auth/refresh{ "refreshToken" }
POST/v1/auth/logoutBearer access token
http
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-->  ready

Poll GET /v1/fulfillment/picker/orders (no WebSocket).

Endpoints

All paths are on the Admin API. GET requires orders:read. POST requires orders:update.

MethodPathBodyPurpose
GET/v1/fulfillment/picker/ordersQueue cards
GET/v1/fulfillment/picker/orders/:orderIdFull order + picking state
POST/v1/fulfillment/picker/orders/:orderId/startClaim; 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/readyFinish; all lines must be handled

Queue card

results.data[] includes _id, orderNumber, status, fulfillmentMode, branch, lineCount, express, optional etaMinutes / deliverySlot, timestamps.

Scan example

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