Importing Products

What Kassly can and cannot bulk-load from a spreadsheet, the exact columns of each import sheet, and what happens when a row is wrong.

19 min read · Updated 25 Oct 2026

Importing products into Kassly from a spreadsheet · 1:26 · Watch on YouTube
On this page

Kassly has four spreadsheet importers. Between them they cover sellable products, raw materials, recipes and stock quantities — and they are worth knowing about before you type a hundred rows by hand.

What the three sheets do

Sheet Where to start What it creates or changes Add-on needed
Products Catalog → Products → Import Creates and updates sellable products: prices, category, VAT, stock tracking, reorder points, opening stock and preferred supplier None
Ingredients Inventory → Ingredients → Import Creates and updates raw-material products, their costs, units, reorder points and opening stock None
Compositions Inventory → Compositions → Import Creates and updates recipes and their ingredient lines Recipe Costing (₱350 per branch each month)
Bulk Stock-In Inventory → Stock Levels → Bulk Stock-In → Import from Excel Adds quantities to products that already exist. Creates nothing None

Two sheets create catalog rows: the products sheet for things you sell, and the ingredients sheet for raw materials. They are kept apart on purpose — a product row never rewrites a raw material of the same name.

Only an Owner or a Manager can import.

How a sheet import works

All four follow the same three steps, and it is worth doing them in order:

  1. Download the template. It comes back already filled in with what you have, so you are editing your own data rather than guessing at a format.
  2. Fill it in. Edit an existing row to update that item; type new rows underneath to add.
  3. Upload it back. Kassly checks every row before it writes anything.

File format

Accepted .xlsx and .xls. The products import also takes .csv (a Loyverse export, or the products template saved as CSV)
Not accepted Google Sheets links, PDF, ODS
Maximum size 5 MB

CSV works for products only. The ingredients, compositions and bulk stock-in imports still need .xlsx: open your CSV in Excel, Numbers or Google Sheets and save it as .xlsx first.

Each template also arrives with a second tab called How to use, which repeats the column rules next to the sheet itself. Do not rename the first tab — the importer looks for it by name and falls back to whichever sheet is open, which is not always the one you meant.

Importing from Loyverse

Moving over from Loyverse? You don't need our template. Upload the items file Loyverse gives you, exactly as it is.

  1. In Loyverse Back Office, go to Items → Item list and click Export. Loyverse downloads a CSV file.
  2. In Kassly, go to Catalog → Products → Import.
  3. Pick the branch that should receive your stock. If your Loyverse account has several stores, pick the Kassly branch with the same name as the store you want. Kassly reads that store's price and stock columns.
  4. Choose the Loyverse CSV and click Import.

What comes across:

Loyverse column Becomes in Kassly
Name Product name
Category Category (created if it doesn't exist; blank goes to Uncategorized)
Default price, or the store's Price Selling price. A blank price means "set at the counter", so the item allows a custom price
Cost (or Purchase cost) Cost price
SKU SKU
Barcode Barcode, leading zeros kept
Option 1–3 name / value Variants. Rows sharing a Handle become one product with a variant per row, e.g. Small / Large
Track stock Track Stock
In stock (for the chosen store) Opening stock at the branch you picked, for items new to Kassly
Low stock Reorder point
Sold by weight Sold by weight, in kg
Available for sale Show in POS
Supplier Preferred supplier, if it matches one on your Suppliers page
Description Description

What doesn't come across, and is listed after the import so you can finish it by hand:

  • Composite items. The item imports, but its "included items" don't. Build the recipe under Compositions.
  • Modifiers. Set up your modifier groups under Modifiers.
  • Taxes. Loyverse tax columns are ignored and items import as Vatable. Change the VAT setting on any exempt item.
  • Negative stock. An item below zero in Loyverse imports without opening stock. Count it and adjust it in Kassly.

Uploading the same Loyverse file again updates your items instead of adding them twice. Stock is only added for items that are new to Kassly, so a second upload never doubles your counts.

The same all-or-nothing rule applies: a bad price or a repeated SKU rejects the whole file with a list of rows to fix.

Loyverse customer exports can't be imported yet. Kassly has no customer importer; send the file through Free setup help on your dashboard and we'll load it for you.

Not on Loyverse, or your list is in some other shape? The dashboard's Free setup help card lets you send us any spreadsheet, and we'll import it for you during your first two weeks.

The products sheet

Start from Catalog → Products → Import. The Export button beside it downloads the same sheet without opening the dialog, which is the quickest way to get your product list into a spreadsheet.

Not signed up yet, or keeping your stock list in Excel? The free inventory list template at kasslypos.com/tools has these same columns, with three example rows and stock value and margin formulas. Fill it in and upload it here as it is. Delete the example rows first, and pick a branch so the Opening Qty lands somewhere. The two grey formula columns after the last heading are ignored on import.

Nineteen columns, in this order.

Col Heading Required Notes
A Name Yes What the item is called on the menu or shelf.
B SKU No Blank generates one. Keep it to update the product on a re-upload.
C Barcode No Scanned at the counter.
D Category On a new product A category that doesn't exist yet is created, so watch the spelling.
E Cost Price No Blank on a new product means 0.
F Selling Price On a new product What the customer pays.
G VAT No Vatable, VAT Exempt or Zero Rated. Defaults to Vatable.
H Track Stock No Yes or No.
I Stock Unit No One of the stock units, e.g. pc, kg, L. Only matters when Track Stock is Yes.
J Opening Qty No Stock to add at the branch you pick. Needs Track Stock set to Yes.
K Reorder Point No Warn when stock falls to this level. Only saved if you pick a branch.
L Show in POS No Yes or No.
M Active No Yes or No.
N Description No Shown on the online store and receipts.
O Sold By No Per piece (default) or By weight/volume/length.
P Supplier No The preferred supplier. Must match a name on your Suppliers page; capitals don't matter.
Q Supplier SKU No The supplier's own code for the item. Up to 100 characters.
R Reorder Qty No How much Inventory → Reorder suggests ordering at the selected branch. Blank leaves it as it is.
S Variant No A size or flavour, e.g. 16oz or Iced. Rows with the same Name and Category and a Variant become one product with variants. See below.

How rows are matched and written:

  • A row updates the product with the same SKU (capitals don't matter), anywhere in your catalog. A row with a blank SKU matches a sellable product of the same name in the same category instead, and never a raw material.
  • A blank cell on an existing product leaves that field alone. Only what you type overwrites what is there, so deleting a column by accident changes nothing.
  • Pick a branch in the dialog if you fill in Opening Qty or Reorder Point — both are per branch.
  • Suppliers are matched, never created. A supplier carries contact details and a TIN the sheet can't supply, so add new suppliers on the Suppliers page first. A name that matches no supplier — or more than one — does not stop the upload: the rest of the row imports, the product's supplier is left as it was, and the dialog lists the skipped cells after the import. See Suppliers.

A sheet downloaded before the Supplier columns existed still imports; its empty P and Q columns simply leave suppliers alone.

Sizes and flavours: one product with variants

An item you sell in sizes or flavours, such as 12oz and 16oz or Hot and Iced, is one product with variants. In the sheet, give each variant its own row: the same Name and Category on every row, and the size or flavour in Variant.

Name SKU Category Cost Price Selling Price Track Stock Opening Qty Variant
Iced Coffee Drinks 35 90 Yes 20 12oz
Iced Coffee Drinks 42 110 15 16oz
Iced Coffee Drinks 50 130 10 22oz

Those three rows import as one product, Iced Coffee, with three variants. The columns not shown are left blank.

Some columns belong to each variant, and the rest to the product as a whole:

Belongs to Columns
Each variant, on its own row SKU, Barcode, Cost Price, Selling Price, Opening Qty, Reorder Point, Reorder Qty
The whole product VAT, Track Stock, Stock Unit, Show in POS, Active, Description, Sold By, Supplier, Supplier SKU

Fill a product-wide column on one row, or repeat it on every row, but the rows that fill it in must agree. Track Stock is Yes on the first row above, which is enough for all three. Rows that disagree are refused: "Row 5: "Iced Coffee" has VAT "VAT Exempt" here but "Vatable" on row 3. Its variants share one VAT, so make the rows match or leave this cell blank."

The rules:

  • An item needs two to 50 variants, as on the product form. A Variant on a single row is refused, because one variant would just repeat the product: clear the Variant cell to sell it as a single item.
  • A new variant needs a Selling Price.
  • Each variant name appears once per item.
  • A variant's SKU must be its own, not one of your products' SKUs. Leave it blank and Kassly numbers it the way the product form does: the product's SKU followed by -1, -2 and so on.
  • Opening Qty goes to each variant's own stock at the branch you pick, and needs Track Stock set to Yes.

Updating works the same way. The template lists a product that already has variants as one row per variant, with Variant filled in, so uploading it unchanged changes nothing. A row updates the variant with its SKU or, when the SKU is blank, the variant of that name on that product. A new Variant name adds a variant. A variant you leave out of the sheet is left as it is: the import never deletes one.

To update a variant, name the product in Name and the variant in Variant. A row without a Variant whose SKU belongs to a variant is refused with a note saying exactly that: "Row 7: SKU "IC-16" is the "16oz" variant of "Iced Coffee". To update it, put "Iced Coffee" in Name and "16oz" in Variant."

Kassly finds the Variant column by its heading, not its letter, so keep the heading Variant. A sheet without that column imports as before, every row a single product.

The same name in two categories

A row without a SKU is identified by its Name within its Category, so a Green Apple soda under Drinks and a Green Apple yoghurt under Yoghurt are two different products. There is no need to number one of them.

  • The same Name twice in one Category, with no SKU or Variant, is refused: "Row 9: "Green Apple" is repeated on row 4. Give each row a unique name or SKU, or list the sizes or flavours of one item in the Variant column."
  • A name the sheet lists under more than one category needs its Category filled in on every row with that name.
  • A name your catalog already holds more than once needs a Category or a SKU on the row, or Kassly can't tell which product you mean: "… matches 2 products in your catalog. Fill in its Category or SKU to say which one."
  • Moving a product to another category still works. If your catalog has the name only once and the sheet lists it under one category, the row updates that product and moves it there. Once a name is in more than one category, a row for a new category creates a new product instead.

The ingredients sheet

Seven columns, in this order.

Column Header Required What to put in it
A Name Yes What you call the raw material.
B SKU No Leave blank and one is generated. Keep the existing value to update rather than duplicate.
C Stock Unit Yes One of pc, g, kg, ml, L. Blank is read as pc. The column has a dropdown.
D Cost per Unit Yes The cost of one Stock Unit — not the price of a whole sack. Sub-centavo values are kept to four decimals.
E Opening Qty No Stock to add at the selected branch.
F Reorder Point No Warn when stock falls to this level.
G Notes No Recorded against the opening stock movement.
H Reorder Qty No How much Inventory → Reorder suggests ordering at the selected branch. Blank leaves it as it is.

The template lists your existing ingredients first and leaves about fifty blank rows underneath to type into. It reads up to about 2,000 rows.

Two things to be careful about:

  • Opening Qty adds, it does not set. The template deliberately leaves it blank on existing rows. Fill it in on a re-upload and you will add that quantity a second time.
  • Opening Qty and Reorder Point need a branch. Both are per branch, so pick one in the dialog. Upload a sheet with quantities and no branch selected and Kassly stops you: "Pick a branch before importing opening quantities — stock has to land somewhere."

How rows are matched

For each row, Kassly looks for an existing ingredient:

  1. by SKU, ignoring capitalisation, then
  2. by exact name, ignoring capitalisation and surrounding spaces.

A match updates the name, unit and cost. No match creates a new ingredient.

Matching only looks at items already flagged as ingredients. A row named after an ordinary product you have not flagged will create a second, ingredient-flagged copy instead of updating it. Flag the item as an ingredient first — the Products page can do it in bulk — then import.

The compositions sheet

This one is in long format: one row per ingredient line. Rows that share the same Menu Item, Variant and Composition Name make up one recipe.

Column Header Required What to put in it
A Menu Item SKU One of A or B The item you sell. Matched first.
B Menu Item One of A or B Used when the SKU is blank.
C Variant No Leave blank if the recipe applies to every size or option.
D Composition Name Yes e.g. Chicken Adobo Standard. Repeat it on every row of the recipe.
E Yield No Servings the listed quantities make. Blank is read as 1. Repeat it on every row.
F Ingredient SKU One of F or G Must already exist.
G Ingredient One of F or G Used when the SKU is blank.
H Quantity Yes How much of the ingredient the whole yield uses.
I Unit No Defaults to the ingredient's stock unit. Any packaging conversion you have set up also works.
J Waste % No 0 to 99.99.
K Producible (commissary) No yes only for batches produced at a commissary. These are not deducted at the point of sale.

You need either the SKU or the name for the menu item, and either the SKU or the name for the ingredient. The SKU wins when both are filled in.

Ingredients must exist before you import recipes. The sheet cannot create them. Run the ingredients import first, or add them on the Ingredients page.

Two rules protect what you already have:

  • A recipe you leave out of the sheet is untouched. A partial sheet is never a mass delete.
  • A recipe that is in the sheet has its ingredient lines replaced by whatever the sheet says. Half a recipe in the sheet means half a recipe afterwards.

It reads up to about 5,000 rows, which is a lot of recipes.

The bulk stock-in sheet

This one changes quantities only — it never creates or edits a product. It also requires you to pick a branch.

Column Header Notes
A product_id Filled in for you. Do not edit or clear it.
B variant_id Filled in for you. Leave alone.
C Product Name For your reference.
D SKU For your reference.
E Variant For your reference.
F Current Qty What is on hand now. For your reference.
G Quantity to Add The one column you fill in. Must be at least 0.01.
H Cost Price Optional. The cost of this batch.
I Batch Number Optional.
J Expiry Date (YYYY-MM-DD) Optional, except for an item set to Require expiry date on stock-in.
K Notes Optional.

Leave a row's Quantity to Add blank and that row is skipped. A row for an item set to Require expiry date on stock-in must have its Expiry Date filled in, or the upload is refused and that row listed: "Paracetamol 500mg needs an expiry date. Enter the date printed on the pack."

Batch numbers and expiry dates are only meaningful with the Inventory Pro add-on — see Batch and expiry — and receiving against a purchase order is a different, better-documented path: see Receiving stock.

What happens to a bad row

All four importers are all-or-nothing. If one row is wrong, nothing at all is saved — you never end up with half a catalog and no idea which half.

Instead the dialog shows a list, in place, under the heading "Nothing was saved — fix these rows and upload again", with one line per problem naming the row number. For example:

Row 14: Cost per Unit must be a number of 0 or more.
Row 22: "Kalamansi" is repeated on row 9. Give each row a unique name or SKU.
Row 31: no ingredient found for "Patis". Add it on the Ingredients page (or import it) first.

The checks that will stop an import:

Sheet Rows are rejected for
Products Missing name; no category or selling price on a new product; a non-numeric or negative cost, price, opening quantity or reorder point; an unrecognised VAT setting, stock unit or Sold By value; a Yes/No column that is neither; an opening quantity on an item that doesn't track stock; the same SKU twice; the same name twice in one category when the SKU and Variant are blank; a name that matches several products, with no Category or SKU to say which; a Supplier SKU over 100 characters. For an item with variants: only one variant, or more than 50; the same variant twice; a new variant with no selling price; product-wide columns that disagree between its rows; a variant SKU that belongs to a product, or a product row whose SKU belongs to a variant.
Ingredients Missing name; an unrecognised stock unit; a non-numeric or negative cost, opening quantity or reorder point; the same SKU twice; the same name twice when the SKU is blank; a SKU that already belongs to a product that is not an ingredient.
Compositions A menu item or ingredient that cannot be found; a missing composition name; an ingredient that does not track stock, since it would never deduct; a quantity of zero or less; a yield of zero or less; waste outside 0–99.99; a variant name the item does not have; the same ingredient twice in one recipe.
Bulk Stock-In A quantity below 0.01; no Expiry Date on an item set to Require expiry date on stock-in.

Fix the sheet and upload it again. Nothing was written, so there is nothing to undo.

Entirely blank rows are ignored, not treated as errors — the templates ship with spare rows on purpose.

One thing is reported without rejecting the file: on the products sheet, a Supplier name that matches no supplier. That row still imports, and the dialog stays open after the import with a note naming the row, so you can add the supplier and set it on the product page.

Re-uploading a sheet

Re-uploading is the normal way to make bulk changes, and both catalog importers are built for it: download, edit, upload, repeat. The one thing that does not survive a careless re-upload is the ingredients sheet's Opening Qty, because it adds rather than sets. Clear that column before you upload again.

The Free plan and imports

New rows count against the Free plan's 50-item limit, and the check happens before anything is written:

"This file would add 40 new items but only 12 remain on your plan. Subscribe to any add-on to unlock unlimited SKUs."

Rows that update an existing item do not count, and an item with variants counts once, however many variant rows it has. See Plans and add-ons.

Getting data out

Exports are separate from imports and more widely available:

  • Compositions — the Export CSV button on the Compositions page gives you the whole filtered list with cost per serving and cost percentage.
  • Products — the Export button on the Products page downloads the products sheet, pre-filled with your catalog.
  • Templates as exports — because every template arrives pre-filled with your current data, downloading one is also the quickest way to get your ingredient list or your recipes into a spreadsheet.

A full reference of every file format Kassly reads and writes is collected in Import formats.