Skip to content

Serialized items — IMEI and serial-number tracking

A serialized product keeps one row per physical unit in the serialized_items table. Every unit carries its own identifier — IMEI, serial number, asset tag — its own cost, and its own status (available, sold, defect, with_supplier, returned). The POS forces the cashier to pick the exact unit at sale time so the receipt prints the right IMEI, returns can be looked up by serial, and warranty work pins to a specific piece.

Updated 5 May 2026·For v2.2.0·5 min read

When to use serialized tracking

Use it when the customer or your operations care which exact unit is which. The most common cases:

  • Phones, tablets, laptops with manufacturer-assigned IMEIs or serial numbers.
  • Firearms, vehicles, registered equipment where regulators or insurance require unit-level traceability.
  • Repair stock where you bill repair expenses against a specific unit and need to recover that history later.

The friction cost is real — every restock asks for one identifier per unit, every sale opens a picker — so don’t reach for it on commodity SKUs where customers don’t care which one they got.

Setting up

1

Create the product with Tracking = Serialized

Open Products → New Product. Set Tracking to Serialized. Two extra fields appear: Identifier label (e.g. “IMEI”, “Serial #”) and a uniqueness toggle that prevents the same identifier from being entered twice.

2

Restock with one identifier per unit

The Restock dialog reshapes itself for serialized products: enter the quantity first, then a row per unit appears with one identifier field and one cost field. Each unit can carry a different cost — there’s no “fill all” shortcut, by design, because two phones from the same supplier often arrive at different prices.

inventory · restock · serialized identifier rows

What changes at the till

Adding a serialized product to the cart opens a picker listing every available unit by identifier. The cashier picks one (or scans the IMEI directly to skip the picker). The picked unit’s status flips from available to sold on checkout, and the identifier prints under the line on the receipt.

If a customer hands you the IMEI on a returned phone, the Returns flow can look up the original invoice by serial — the wizard surfaces the matching invoice and pre-fills the right line.

Per-unit cost

Each serialized unit’s cost is captured at restock and stamped on the unit’s row. When a sale walks the FIFO resolver, the priority chain reads the per-unit cost from serialized_items.cost first — only falling back to FIFO layers or the product’s stored cost if a serialized record is missing one (legacy data). This is what lets you sell a $400 phone at $400 COGS and a $450 phone at $450 COGS, even when both are the same model.

See FIFO costing for the full priority chain.

The tracking page

Open Inventory → View Tracking on a serialized product to see every unit:

  • Identifier — IMEI / serial.
  • Statusavailable, sold, defect, with_supplier, or returned. Filter by status from the toolbar.
  • Supplier — who you bought it from.
  • Variant — if the product is also variable, the variant attributes for this unit.
  • Linked expense — when you logged a repair expense against this unit (the Expenses module supports serialized item linking), it shows here.
  • Dates — received, sold, returned.

Click any unit to drill into its full timeline — restock event, the invoice that sold it, any return, any defect routing.

Returns and defect routing

Bulk import

For shops that bulk-receive a delivery of, say, 200 phones with a separate spreadsheet of IMEIs, use the CSV import path on the Restock dialog instead of typing rows by hand. Format: one identifier per line, optional cost in a second column. The dialog ingests the file and pre-fills the rows; you confirm and post the restock as one transaction.