Importing your SKU catalog from a CSV
Your SKU catalog is your materials price list — one row per part you buy (a breaker, a length of wire, a device box), each with a code, a description, a unit price, and a unit of measure. Flow's bid builder pulls from this list so line-item pricing starts from real numbers instead of guesses. Rather than type every part in by hand, you can upload a CSV and create the whole list at once.
Find it under Settings → Catalog → Import from CSV. Out of the box only an owner can run an import.
Upload a .csv file with the columns below and click Import SKUs. Flow
checks every row first. If they're all good, it creates any new SKU and
updates any SKU whose code it already has, then tells you how many it created
and updated. If any row has a problem, nothing is imported and Flow lists
the rows to fix. New parts land in the catalog's Needs review list so
someone looks them over before they go on a real bid.
The exact columns
Your file needs a header row, then one data row per SKU. Column order does not
matter — Flow matches on the header name, not position. Header names are
matched case-insensitively and trimmed, so SKU_Code and sku_code both
work. Any extra columns are ignored.
| Column | Required? | What it is |
|---|---|---|
sku_code |
Required | Your code for the part. This is the identity of the row — see Import updates existing rows. |
description |
Required | Plain-English name of the part. |
unit_price |
Required | Price as a plain number (for example 12.50). Must be zero or greater. |
unit_of_measure |
Required | The unit you buy in — each, ft, box, and so on. Free text; Flow doesn't check it against a list. |
supplier_name |
Optional | Who you buy it from. See How suppliers are handled. |
default_waste_percent |
Optional | How much of this part you typically buy but don't install, as a percent — 10 means 10%. See The waste column. |
If your header is missing any of the four required columns, Flow rejects the whole file before importing anything and tells you which columns it expects.
Example CSV
sku_code,description,unit_price,unit_of_measure,supplier_name,default_waste_percent
BRK-20A-1P,20A single-pole breaker,8.75,each,Graybar,0
WIRE-12-2-250,12/2 NM-B wire 250ft roll,89.00,box,Graybar,15
BOX-1G-PVC,1-gang PVC device box,1.10,each,,
That third row has an empty supplier_name and an empty
default_waste_percent, which is fine — both columns are optional, and you can
leave any single cell blank.
What Flow checks, row by row
Flow checks each data row on its own, and a single bad row stops the whole import. A row has a problem when:
sku_codeis blank → "Missing sku_code"descriptionis blank → "Missing description"unit_of_measureis blank → "Missing unit_of_measure"unit_priceisn't a number, or is negative → "Invalid unit_price: …"default_waste_percentisn't a number, or is negative → "Invalid default_waste_percent: …"default_waste_percentis over 100 → "…this column is a percent, so 10 means 10%"
If every row is good you'll see a green summary like "Import complete: 12 created, 3 updated." If any row has a problem you'll see Nothing was imported, and under it Fix these rows and upload again: with each row and why. Fix them and upload the whole file again. The row number is the line number in your file — the header is row 1, so your first SKU is row 2.
Values may be wrapped in double quotes if they contain commas (for example a
description like "lug, 2-hole"), and a doubled quote "" inside a quoted
value is read as one literal quote.
Import updates existing rows in place
The import is an upsert, keyed on sku_code:
- If a SKU with that code doesn't exist yet, Flow creates it.
- If a SKU with that code already exists, Flow updates it in place — overwriting the description, unit price, unit of measure, and supplier from your file, and stamping a fresh "last refreshed" time.
So you can re-upload an updated price list any time and Flow will refresh the
prices you already have rather than making duplicates. The sku_code is what
ties an upload back to an existing row, so keep your codes stable.
One thing to watch: an update overwrites the supplier from your file every
time. If an existing SKU is linked to a supplier and you re-import that row with
supplier_name blank (or without the column at all), Flow clears the
supplier link on that SKU. Include the supplier name on every row you want to
keep linked.
The waste column
default_waste_percent is how much of a part you buy but don't install — the
offcuts, the bends, the wire nut that ends up in the insulation. Conduit is
usually about 10%, Romex about 15%, wire nuts about 20%, and a device box is 0%
because you buy seven and install seven.
Put it on the part once, and every takeoff line you add for that part starts from it. You can still change the waste on any individual line — a run that's unusually clean or unusually chopped up is a per-job fact — but you no longer have to remember the number every time. Left blank, a line used to price at 0% waste, which quietly under-buys.
Two details worth knowing:
- It's a percent, not a multiplier. If your spreadsheet writes
1.10for 10% conduit waste, write10here. Flow refuses anything over 100, because that's almost always a multiplier typed by mistake. - Blank means "not stated", not "zero". If you re-upload a price list
without the column, or with that cell empty, Flow leaves the waste you already
had alone. To actually set a part to no waste, write
0.
How suppliers are handled
supplier_name is optional. When you do provide one, Flow looks for a supplier
by that exact name:
- If it finds one, it links the SKU to that existing supplier.
- If it doesn't, it creates a new supplier with that name for you (marked as sourced from CSV upload).
Matching is by exact name, so Graybar and Graybar Electric become two
different suppliers. Keep the spelling consistent across your file.
What's not in v1 yet
Being straight with you about the current limits:
- This importer only does parts (and the suppliers they name). Kits and the work you offer at the site visit are built by hand in Settings → Catalog. Suppliers get created only as a side effect of a row that names them.
- No template download. Flow can't hand you a blank starter CSV. But Export CSV on Settings → Catalog downloads your current catalog with exactly these columns (plus category, review status and whether it's retired, which the import ignores), so the easiest starting file is an export: edit it in a spreadsheet and import it back.
- No undo. A good file is imported in full. To back out a wrong price, re-upload corrected rows.
- Leaving a part out doesn't remove it. The importer only creates and updates. Retire or delete an old part on its page in Settings → Catalog.
- The parser is simple. It reads a plain comma-separated file with quoted fields. It doesn't handle other delimiters, and — unlike the data rows — the header line isn't quote-aware, so keep your header names plain.
Who can do this
Out of the box, catalog import is owner-only. If the import screen isn't available to you, ask an owner to run it, or to give you Change settings in People.
Related
- Labor roles and payroll burden — the other half of your bid pricing inputs
- Catalog items, kits and work — building kits and work from the parts you import
- Building a bid — how catalog parts flow into the materials takeoff