# Reorder status

Find products below configured reorder points and see the exact projected gap.

Canonical HTML: https://developer.shelfcycle.com/guides/reorder-status

Find configured product-and-warehouse reorder points that need attention, with current stock, demand context, projected availability, the exact threshold gap, and complete status counts.

Use `GET /reorder-status` for dashboards, worklists, and connected assistants that need to review the reorder points already configured in ShelfCycle.

## Access

The endpoint requires `reorder:read` plus the acting user's current access to view Products and Lots. `GET /me` reports the result through `effectiveCapabilities.reorder.status.view` and `effectiveCapabilities.reorder.status.currentStateRefresh`.

```bash
curl "$SHELFCYCLE_API_BASE_URL/reorder-status?status=below_on_hand&limit=25" \
  -H "Authorization: Bearer $SHELFCYCLE_API_KEY" \
  -H "X-ShelfCycle-Client: Reorder attention dashboard"
```

## Filters

| Parameter | Use it for |
| --- | --- |
| `productId` | One exact product. |
| `productFamilyId` | Configured products in one family. |
| `warehouseId` | Configured products at one physical warehouse. |
| `status` | `below_on_hand`, `below_projected`, or `ok`. |
| `limit` | Rows per page from 1 to 100. The default is 25. |

Filters can be combined on the first request. Status counts continue to cover the complete product, family, and warehouse selection before the status filter, so one filtered response can still power an accurate summary.

## Read a reorder row

```json
{
  "data": [
    {
      "type": "reorder_status",
      "product": {
        "id": "product-id",
        "code": "IPA-DRUM",
        "family": { "id": "product-family-id", "name": "Isopropyl Alcohol" }
      },
      "warehouse": { "id": "warehouse-id", "name": "Main Warehouse" },
      "basis": {
        "type": "package_count",
        "unitOfMeasure": "GALLON",
        "packaging": { "id": "packaging-id", "name": "55 gallon drum" }
      },
      "reorderPoint": "12",
      "onHand": "16",
      "allocated": "3",
      "committed": "5",
      "projectedAvailable": "8",
      "projectedDeficit": "4",
      "status": "below_projected"
    }
  ],
  "meta": {
    "configuredRows": 18,
    "returnedRows": 1,
    "hasMore": false,
    "statusCounts": {
      "scope": "entity_filters_excluding_status",
      "belowOnHand": 4,
      "belowProjected": 3,
      "ok": 11
    },
    "configuredCoverage": {
      "configuredProducts": 14,
      "activeProducts": 92,
      "excludedArchivedConfigured": 2,
      "excludedDirectShipConfigured": 0
    },
    "nextCursor": null,
    "ordering": "product_id_asc_warehouse_id_asc",
    "observedAt": "2026-08-24T16:30:00.000Z",
    "currentState": true,
    "snapshotIsolatedAcrossRequests": false,
    "requestId": "request-id"
  }
}
```

All quantities are decimal strings in the row's stated basis. `projectedAvailable` is on hand less allocated and committed quantities. `projectedDeficit` is the gap between the configured reorder point and projected availability, with `0` when projected availability meets or exceeds the threshold.

Use `projectedDeficit` to show how far a position sits below its configured threshold. Pair it with `allocated` and `committed` to explain the current demand behind the result while keeping the row's quantity basis visible.

| Status | Meaning | Display label |
| --- | --- | --- |
| `below_on_hand` | Current on-hand quantity is below the configured reorder point. | Critical |
| `below_projected` | On hand is at or above the reorder point, but projected availability after allocations and committed demand is below it. | Low |
| `ok` | Projected availability is at or above the configured reorder point. | OK |

> **Planning context**: Reorder status includes committed demand and does not include inbound or on-order quantities. Keep that distinction visible when presenting a below-threshold result.

## Use complete counts

Use `meta.statusCounts` for summaries instead of counting the current page. The counts cover the selected product, family, and warehouse population before the `status` filter.

Use `meta.configuredCoverage` to explain how much of the active product population has reorder points configured. For the example above, say "14 of 92 active products have reorder points configured; 4 configured positions are Critical and 3 are Low." Do not describe that result as the health of all 92 products.

A response with `configuredRows: 0` means no reorder points are configured in the selected scope. A status-filtered response can return no rows while `statusCounts` still shows the complete configured population.

## Continue and refresh

When `meta.hasMore` is true, call the endpoint again with `meta.nextCursor` by itself:

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

Do not combine a cursor with the original filters. The cursor retains the selection, status, page size, ordering, organization, and key needed for continuation.

Each response is a current view observed at `meta.observedAt`. For a complete refresh, restart from the original filters and continue through the newly returned cursors.

> **Guardrail**: Keep each row's product, warehouse, quantity basis, and unit with its quantities. Compare or add values only when that context makes the operation meaningful.
