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. Only a tenant owner can run an import.
Upload a .csv file with the columns below and click Import SKUs. Flow
reads each row, creates any new SKU, and updates any SKU whose code it already
has. When it finishes, it tells you how many rows it created, how many it
updated, and lists any rows it had to skip.
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. |
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
BRK-20A-1P,20A single-pole breaker,8.75,each,Graybar
WIRE-12-2-250,12/2 NM-B wire 250ft roll,89.00,box,Graybar
BOX-1G-PVC,1-gang PVC device box,1.10,each,
That third row has an empty supplier_name, which is fine — the column is
optional, and you can leave any single cell blank.
What Flow checks, row by row
Flow validates each data row on its own. A row that fails is skipped and reported — the rest of the file still imports. A row is skipped 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: …"
After the import runs you'll see a green summary like "Import complete: 12 created, 3 updated, 2 errors," and, if there were errors, an orange list naming each skipped row and why. 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.
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 SKUs (and the suppliers they name). Your catalog also includes task codes and other reference data, but this screen doesn't import those — only the materials price list. Suppliers get created only as a side effect of a SKU row that names them.
- No export and no template download. Flow can't hand you a starter CSV or export your current catalog. You build the file yourself; the column list above is the spec.
- The import isn't all-or-nothing. Rows are saved as they're processed, so a file with some good rows and some bad ones leaves the good rows imported and reports the bad ones. There's no undo — to back out a bad import, re-upload corrected rows.
- Deletion isn't supported. Leaving a SKU out of a later upload doesn't remove it; the importer only creates and updates. Remove obsolete parts elsewhere.
- 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
Catalog import is owner-only. If the import screen isn't available to you, sign in as the tenant owner.
Related
- Setting your labor rates — the other half of your bid pricing inputs
- Building a bid (coming soon) — how SKUs flow into line-item pricing