# Lot movements

Trace recorded receipts, shipments, and production with per-lot running balances.

Canonical HTML: https://developer.shelfcycle.com/guides/lot-movements

Follow recorded receipts, shipments, and production activity with quantities and running balances kept with each named lot.

## Access

`GET /lot-movements` uses `lots:read` and the acting person's current Product and Lot viewing access. Related identities have separate access requirements:

- Purchase-order IDs, numbers, and types require `purchase-orders:read` and current Purchase Order viewing access.
- Sales-order IDs and numbers require `orders:read` and current access to that order.
- Customer identity requires `customers:read` and current access to that customer.
- Supplier identity requires `suppliers:read` and current Supplier viewing access.

Work-order movements report their kind and `workOrderVersion`; their document ID and number remain `null`.

## Choose a lot or period

Send `from` and `to` together as inclusive `YYYY-MM-DD` organization-calendar days covering at most 366 days. Alternatively, select a `lotId` or exact `lotNumber` without a date window. Do not send both lot selectors. A selected lot can also be narrowed by a date window.

```bash
curl "$SHELFCYCLE_API_BASE_URL/lot-movements?from=2026-10-01&to=2026-10-23&warehouseId=warehouse-id&limit=100" \
  -H "Authorization: Bearer $SHELFCYCLE_API_KEY"
```

Optional `productIds` is a comma-separated list of up to 120 exact product UUIDs and selects which lots are read. Other filters are `warehouseId`, `customerId`, and `salesOrderId`. Customer and sales-order filters require the matching read access. Add `includeDirectShip=true` or `includePlaceholders=true` when those lots belong in the review. `limit` accepts 1 to 100.

## Read movements and balances

Each row includes `occurredOn`, `direction` (`in` or `out`), `movementType`, `workflow`, `quantity`, `runningBalance`, and its lot, product, warehouse, and `quantityBasis`. Movements within a lot are oldest first.

`movementType` is `purchase_receipt`, `sales_shipment`, `production_output`, `production_input`, or `unclassified`. `workflow` distinguishes `production`, `warehouse_transfer`, and `relabeling` when recorded. Production inputs and outputs remain production movements even when their workflow is a transfer or relabeling.

Read decimal-string quantities in the lot's stated package-count or base-unit basis. Do not add quantities across unrelated lots or units. Customer and sales-order filtering selects visible events after the running balance is calculated, so that balance still describes the full lot, not just the displayed customer's movements.

## Keep coverage with the answer

`meta.summary` describes the complete matching population and repeats on every page. It reports event, lot, warehouse, basis, and group counts, grouped movement quantities, and `limitationLotCounts`. Do not add the summary again for each page.

`meta.lots` covers lots on the current page, with `openingBalance`, `closingBalance`, and any recorded `limitations`. Keep `below_zero_balance`, `history_disagrees_with_on_hand`, and `header_inconsistent` evidence with the affected lot rather than treating a movement-derived balance as a guaranteed current on-hand quantity. Use [Lots](/guides/lots) for the stored current quantities and COA readiness.

## Continue and refresh

When `meta.nextCursor` is present, send it by itself:

```bash
curl "$SHELFCYCLE_API_BASE_URL/lot-movements?cursor=$NEXT_CURSOR" \
  -H "Authorization: Bearer $SHELFCYCLE_API_KEY"
```

These are current-state reads. Retain `meta.observedAt` with the review and restart the original filtered request when a fresh view is needed.
