Overview
The CSV import builds or updates your whole product list in one upload instead of typing items one by one.
Where: open Inventory in the app and choose Import CSV ("Bulk upload products").
Start from an export. Export CSV downloads your current products in exactly the format the import accepts: edit the file and import it back to update in place.
What an import does:
- Creates products that don't exist yet.
- Updates products that match on SKU or Barcode: only the columns present in your file are overwritten.
- Creates missing categories automatically (unless your plan's category limit is reached).
- Writes a stock movement for every stock quantity change (reference
CSV_IMPORT), so inventory history stays accurate. - Revives a previously deleted product when its SKU or barcode matches.
Imports follow your plan: the CSV Import / Export feature and your plan's product/category limits apply. Rows beyond a limit are skipped and listed in the import report.
File format
Accepted file types: .csv, .txt, .tsv: maximum 10 MB. Excel workbooks are rejected, so in Excel use File → Save As → CSV.
The first row must be a header row. Column order does not matter: columns are matched by name, not position. Unknown columns are ignored.
| Column | Recommended | Example | Notes |
|---|---|---|---|
| Name | Yes | Sugar 1kg | Product name. Rows without a name are skipped. |
| SKU | Yes | SUG-001 | Unique code used to match existing products. Auto-generated if blank. |
| Barcode | No | 6001240100015 | EAN/UPC. Second match key when SKU doesn't match. |
| Category | No | Groceries | Missing categories are created automatically (plan limits apply). |
| Price | Yes | 2500 | Selling price. Commas and spaces are stripped ("2,500" works). Blank becomes 0. |
| Cost Price | No | 1800 | Leave the whole column out to keep existing cost prices untouched. |
| Stock | No | 40 | Stock on hand. Changes write a stock movement. |
| Min Stock | No | 5 | Low stock alert level. |
| Unit | No | pc | Measurement unit; defaults to pc. |
| Description | No | 1kg packet | Long description / notes. |
| Is Active | No | yes | false, no, off, inactive or disabled deactivate the product. |
The delimiter is detected automatically (comma or semicolon) and UTF-8 or Excel (BOM/UTF-16) files are accepted.
Column name matching
Headers do not have to match exactly: common export headers from other POS and stock systems are recognized:
| Field | Accepted headers include |
|---|---|
| Name | Name, Product Name, Item Name, Title, Product, Item |
| SKU | SKU, Product Code, Item Code, Code, Article, Reference, Part Number |
| Barcode | Barcode, Bar Code, EAN, UPC, GTIN |
| Category | Category, Category Name, Product Group, Group, Department |
| Price | Price, Selling Price, Retail Price, Sale Price, RRP, MRP |
| Cost Price | Cost, Cost Price, Buy Price, Purchase Price, Unit Cost, Landed Cost |
| Stock | Stock, Quantity, Qty, Stock Qty, Stock on Hand, On Hand, Inventory |
| Min Stock | Min Stock, Minimum Stock, Reorder Point, Reorder Level, Low Stock Level, Alert Quantity |
| Unit | Unit, UOM, Measure, Unit of Measure |
| Description | Description, Notes, Note, Details |
| Is Active | Is Active, Enabled, Status, Active, Visible |
If a header is not in the table, keyword matching still finds a close fit (for example "Reorder warning" → Min Stock, "Purchase price" → Cost Price). Headers that start with "Is " or "Has " are treated as flags, not quantities.
If no name column can be found at all, the import stops with an error listing the headers it saw: that message tells you exactly what to rename.
How rows are matched and updated
For every data row the importer looks for an existing product:
- SKU match first (including soft deleted products: they are revived so the import updates one canonical row).
- Barcode match second.
- No match → the row creates a new product (slug is generated from the name; a random SKU is assigned if the SKU column is blank).
When a match is found, only columns present in your file are written:
- A file without a Cost Price column never zeroes out existing costs, and a file without SKU never swaps in a random one.
- A stock change records a movement (
CSV_IMPORT, with the row number in the notes) and updates the global stock level. - The result line reports how many rows were created and updated, e.g.
Import complete. 24 created, 6 updated.
Common errors
| Message | What to do |
|---|---|
| Unsupported file type (".xlsx") | Save the file as .csv (or .txt / .tsv). |
| This looks like an Excel workbook (.xlsx) | In Excel: File → Save As → CSV. |
| Could not find a product name column. Found headers: … | Add a Name / Product Name column: the error lists every header it saw. |
| CSV file is empty or has no data rows | Make sure row 1 is the header and at least one data row follows. |
| Row N: Missing name, skipped | Fill in the product name for that row. |
| Row N: Non-numeric value in price, cost, stock, or min_stock, skipped | Remove currency symbols and text from those cells. |
| Row N: product limit (X) reached: skipped. Upgrade your plan… | Your plan's product limit was hit: upgrade or delete unused products. |
| Category limit (X) reached: new category names imported without a category | Free up category slots or upgrade the plan, then re-import. |
| File is rejected with an authentication/feature error | CSV import requires a plan with CSV Import / Export enabled. |