Skip to content

Importing products

You sell a list of products and want them in BatchDash before writing a single recipe. The products import turns one row into a product: a recipe to fill in later, one sales format, and the stock you already hold in that format. It is the door in for a maker arriving from another tool. The upload, mapping and per-row checks work the same for every import kind; see CSV imports for that flow. You reach it from the Import menu on the Products page.

The products import before a file is dropped

Field Required What goes in it
Name Yes The product’s name, which becomes the recipe’s name, e.g. “Smoked habanero hot sauce”
Code No Your recipe code; left blank, BatchDash makes one from the name
Format No The container noun: jar, pouch, tube. Blank means one unnamed default format
Fill quantity No What the format holds, e.g. 250. Give the unit with it
Fill unit No The unit of that fill: ml, g, kg, L
Variant No One short word for this version of the recipe: a scent, a flavor, a colorway
Barcode number No The format’s GTIN, 8, 12, 13 or 14 digits
SKU No Your own code for the format, unique in your workspace
Opening stock No Units on hand of this format, in the format’s own unit
Unit cost No What one unit cost to make; with an opening stock, it seeds the product’s cost figure

Common header names map on their own: “barcode” finds Barcode number, “on hand” finds Opening stock. Anything else you match by hand under Column mapping. Download a template gives you the headers ready to fill.

A committed row creates a product recipe with no ingredient lines, the format described by the row, and the sellable line you will count stock on. The recipe itself is written afterwards on its recipe page: the import knows the product’s name, never its ingredients.

A row with no format, no fill and no variant creates the recipe with one unnamed default format, the same shape as a product created by hand. A row with “jar”, 250 and ml creates a “250 ml jar” format on it. Three rows named “Smoked habanero hot sauce” with three formats create one recipe and three formats, because the second and third rows attach to the recipe the first one made.

A row whose code matches one of your recipes attaches its format to that recipe instead of creating a new one. Failing a code, an exact name match does the same when exactly one recipe carries that name. When several recipes share the name, the row is flagged “Several recipes carry this name. Map it to the right one.” and Map to recipe on the row lets you choose; the same picker overrides any match you disagree with.

A recipe holds at most eight formats. A row that would add a ninth is flagged “This recipe already has 8 formats.”; a row describing a format the recipe already has is flagged “This recipe already has this format.”; a blank-format row on a recipe that already has its default format is flagged “This product already exists.” None of these rows is imported until you change it.

Opening stock posts only for formats the import creates, so re-running the same file never double-counts. With a unit cost, the stock is costed and the product’s unit cost figure starts from it; without one, the quantity is on hand uncosted and the cost card says what is missing, exactly like a product created before its first batch. A unit cost without an opening stock is ignored: there is nothing to cost.

A barcode number is checked for length and for its check digit; a bad one flags the row with the reason. A SKU is at most 32 characters of unaccented letters, digits, hyphens, dots, underscores and slashes, stored in capitals, and must be free in your workspace; “This SKU is already used.” flags a taken one, in your records or earlier in the file. A variant is at most 60 characters and composes after the recipe name wherever the product shows, as described in sellable products.

It cannot write recipe content, attach a packaging set, set prices or record a batch. Those live on the recipe page, the product page and the runs. Products count against your plan’s recipe quota, one per recipe the import creates: a batch that would cross the limit is refused before any of its rows is written, and the message names the limit.