CSV import
The fastest way to fill a fresh organization is a CSV import — the self-setup path most new customers take. One upload can carry products, serialized items, quantity stock, and meter readings together. You run it from Admin → Import; it needs the products.create and items.create permissions.
One file, a "kind" column
Every row starts with a kind column that says what it is — product, item, stock, or reading (the plural forms work too). A single file may mix all four. The importer runs in two passes, so an item or stock row may reference a product defined anywhere in the same file — earlier or later — by its name (plus model) or by a short ref you assign. Products are matched by name + model and are idempotent: one that already exists is skipped with a warning, not duplicated.
The four row kinds
| kind | What it creates | Key columns |
|---|---|---|
product | A catalog definition (manufacturer, model, tracking mode). | name, manufacturer, model, category, tracking_mode, department |
item | A serialized asset that hangs off a serialized product. | product / product_ref, serial_number, condition, location |
stock | An opening quantity for a quantity-tracked product, as a purchase movement. | product / product_ref, location, quantity, min_quantity, unit |
reading | A meter reading against an existing item (by asset tag). | asset_tag, meter, value, read_at |
The exact header row for each kind:
kind,name,manufacturer,model,category,tracking_mode,description,url,ref,department
kind,product,product_model,product_ref,serial_number,condition,location,purchase_date,purchase_price,currency,supplier,notes
kind,product,product_model,product_ref,location,quantity,min_quantity,unit
kind,asset_tag,meter,value,read_at,note
Download a template
From Admin → Import, use the Download template buttons to get a ready CSV with the header row already in place — one each for products, items, and stock. Fill it in a spreadsheet, export as CSV (UTF-8), and upload. The same screen also offers a starter template library of common theatre gear, so a small org can skip the spreadsheet entirely.
Locations and categories by name
Put locations and categories in as name paths with / between levels — e.g. Main stage / Rack B. A path that already exists is matched (case- insensitively); an unknown path is an error unless you tick create missing, which spawns the nodes parents-first. Creating locations needs locations.manage; creating categories needs admin.taxonomy.manage.
How validation works
- Two steps. You upload, get a per-row report (each row marked
ok,warning, orerror), then confirm. Apply re-runs the same validation server-side — nothing changes until you commit. - Errors block the file. Nothing lands while any row is in error, unless you choose to skip error rows and import only the clean ones.
- Warnings still import — a skipped duplicate product, or a path that will be created, is a warning, not a stop.
- Up to 2000 rows per file (imports run synchronously within the Worker's limits). Split a bigger dataset across files.
Field rules
| Column | Rule |
|---|---|
tracking_mode | serialized (default) or quantity. |
department | Optional. The owning department's name or key; empty means Shared. An unknown department errors the row. |
condition | new, good (default), fair, or poor. |
purchase_date | ISO date, e.g. 2026-03-14. |
purchase_price | A decimal amount (up to 2 places); currency is a 3-letter code, defaulting to the org currency. |
quantity | A whole number ≥ 1 (stock rows). |
| product vs item vs stock | item rows need a serialized product; stock rows need a quantity product — a mismatch errors. |
value | A non-negative meter value; read_at is an ISO date or datetime. |
purchase movements on the ledger — the same append-only path every other stock change uses — so your opening balances are auditable from day one. See Getting started for the setup order (locations and categories first), and Items & products for what the catalog layer holds.