Order lifecycle & cancellation
Order state is primarily unified_json.status (string, max 128 chars). Workers, rider apps, simulators, and PATCH /v1/orders/:id update this field. orders.cancelled_at is set when a cancel succeeds.
Typical statuses
Integrations usually observe:
| Status | Typical meaning |
|---|---|
pending | Created / awaiting dispatch |
accepted | Rider accepted |
picked_up | Picked up at merchant |
in_transit | En route to customer |
delivered | Completed |
cancelled | Voided |
Additional strings may appear (in_transit_delayed, returned_to_merchant, lost_in_transit, etc.) — treat unknown values gracefully.
Merchant cancel — POST /v1/orders/:id/cancel
- Auth:
orders:writeonilv_…or merchant JWT (same billing gates asPOST /v1/orders;keys:managetoo whenORDER_POST_REQUIRES_KEYS_MANAGE=1). - Body: optional
reason(defaults to a generic API string), optionalnotes. - 200 — order cancelled, or
already_cancelled: trueon replay. - 409
cannot_cancel— disallowed status (see below). - Fires
order.status_updatedoutbound withprevious_statusandstatus: cancelled.
Policy (aligned with admin cancel)
- Default: cancel allowed until terminal fulfilment:
delivered,returned_to_merchant,lost_in_transit. ADMIN_ORDER_CANCEL_PRE_PICKUP_ONLY=1: stricter — cancel blocked frompicked_up,in_transit, terminal outcomes, etc. (same env as admin break-glass cancel).
Admin cancel — POST /v1/admin/orders/:orderId/cancel
Operator/support path with admin RBAC. Same merge to cancelled and audit order.admin_cancelled. Use when the merchant API cannot proceed (account locked, dispute, etc.).
Status changes without cancel
Merchants may PATCH /v1/orders/:id with status / payment_verified when permitted (commission and env gates apply). Rider flows and simulators advance statuses and emit webhooks (order.picked_up, order.delivered, etc.).
Next steps
- Orders & Deliveries — Request examples
- Webhooks & Events — Payload shape & retries
- Integrator readiness — Full checklist