> ## Documentation Index
> Fetch the complete documentation index at: https://docs.stateset.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Lot and serial traceability

> Lots, serials, reservations, quarantine, and NCRs — answering "which units are affected and where are they" in minutes.

# Lot and serial traceability

Traceability answers one question under pressure: **a defect or recall exists — which units are
affected, and where is every one of them?** The answer is only fast if identity was captured at
every handoff. This guide is the discipline, and the payoff.

Two granularities:

|            | Tracks                    | Use for                                                                          |
| ---------- | ------------------------- | -------------------------------------------------------------------------------- |
| **Lot**    | A batch (`lot_2026_07_A`) | Anything made or received together — consumables, food, cosmetics, components    |
| **Serial** | One physical unit         | Warrantied goods, electronics, anything an individual unit's history matters for |

## Capture at receipt

Lots and serials are created when goods [arrive](/guides/commerce/receiving-and-putaway):

```bash theme={null}
curl -X POST https://api.stateset.com/api/v1/lots \
  -H "Authorization: Bearer $STATESET_API_KEY" \
  -H 'content-type: application/json' \
  -d '{ "sku": "CREAM-50ML", "lot_number": "L2026-07-A", "quantity": 480, "expires_at": "2027-07-01" }'
```

```bash theme={null}
curl -X POST https://api.stateset.com/api/v1/serials \
  -H "Authorization: Bearer $STATESET_API_KEY" \
  -H 'content-type: application/json' \
  -d '{ "sku": "DEVICE-X", "serial_number": "SN-4419-2210" }'
```

<Warning>
  Identity capture is all-or-nothing per SKU. A lot-tracked product with *some* untracked units has no
  recall story — the untracked units are exactly the ones you cannot find. If you turn tracking on,
  backfill or quarantine the untracked stock.
</Warning>

## Reserve and consume

Reservations tie identity to demand *before* the goods move — an order, a work order:

```bash theme={null}
curl -X POST https://api.stateset.com/api/v1/lots/{id}/reserve \
  -H "Authorization: Bearer $STATESET_API_KEY" \
  -H 'content-type: application/json' \
  -d '{ "quantity": 24, "reference": "wo_1201" }'

# release if the demand goes away:
curl -X POST https://api.stateset.com/api/v1/lots/reservations/{reservation_id}/release \
  -H "Authorization: Bearer $STATESET_API_KEY"
```

Consumption (`POST /api/v1/lots/{id}/consume`) records the lot into what it became — a
[production batch](/api-reference/commerce/production_batches/production-batches-list) records which
component lots went into which finished lot, which is the link a recall walks. Serials mirror the
moves: `/{id}/ship` on the way out, `/{id}/return` on the way back,
`/{id}/scrap` at end of life.

## Expiry

```bash theme={null}
curl "https://api.stateset.com/api/v1/lots/expiring?within_days=60" \
  -H "Authorization: Bearer $STATESET_API_KEY"
```

Run it weekly. Expiring stock found at 60 days is a promotion; found at 5 days it is a
[write-off](/guides/commerce/ar-collections#uncollectable--write-off). Pickers consuming
oldest-first only works if lot dates were captured at receipt — see the warning above.

## Quarantine and quality

The moment a lot is suspect:

```bash theme={null}
curl -X POST https://api.stateset.com/api/v1/lots/{id}/quarantine \
  -H "Authorization: Bearer $STATESET_API_KEY" \
  -H 'content-type: application/json' \
  -d '{ "reason": "customer reports of separation, NCR-88" }'
```

Quarantined stock is off sellable inventory immediately — picks stop finding it *while* you
investigate, not after. The investigation itself is a quality workflow: an inspection
(`POST /api/v1/quality/inspections`, then `/start`, `/results`, `/complete`) and an NCR
(`POST /api/v1/quality/ncrs`) whose **disposition** (`/{id}/disposition`) decides the lot's fate —
release (`POST /api/v1/lots/{id}/release-quarantine`), rework, [return to
vendor](/guides/commerce/returns-and-rtv#return-to-vendor), or scrap.

## The recall drill

When it's real, the sequence is four reads and one write:

1. `GET /api/v1/lots?lot_number=L2026-07-A` — the lot, its remaining quantity
2. `GET /api/v1/warehouse-locations/{id}/inventory` — where the on-hand units sit
3. Shipped units — the lot's consumption and shipment history names the orders, which names the
   customers
4. `POST /api/v1/lots/{id}/quarantine` — stop further movement, then work the list

<Tip>
  Run this drill on a fake defect once a quarter and time it. The gap between "minutes" and "days" is
  entirely determined by capture discipline at receipt — and it is much cheaper to discover a hole in
  the drill than in the recall.
</Tip>

## Related

* [Receiving and put-away](/guides/commerce/receiving-and-putaway) — where capture happens
* [Returns and RTV](/guides/commerce/returns-and-rtv) — defective units coming back
* [Manufacturing quality reference](/api-reference/commerce/overview#manufacturing-and-quality)
