Importing a menu from CSV
Populate a whole menu — categories and products — from one spreadsheet.
1. Download the template
On the Menus page, use Download template. The columns are:
| Column | Required | Notes |
|---|---|---|
category |
yes | Categories are created in the order they first appear. (section, the old name for this column, still works in older files.) |
name |
yes | The product name (max 120 characters). |
description |
no | Shown on guest tiles. |
price |
yes | Major units, e.g. 9.50. No currency symbols. |
tax_category |
yes | Must match one of your tax categories by name (see the Tax page). |
kind |
yes | DISH or DRINK. |
station |
no | Prep station, e.g. GRILL — leave blank for the default. |
allergens |
no | Pipe-separated UK FSA codes, e.g. GLUTEN|MILK. Valid codes: CELERY, GLUTEN, CRUSTACEANS, EGGS, FISH, LUPIN, MILK, MOLLUSCS, MUSTARD, PEANUTS, SESAME, SOYBEANS, SULPHITES, TREE_NUTS. Blank = unspecified — an existing product keeps its current allergens. |
available |
no | yes or no (86 state). Blank = leave unchanged. Flipping it on an unchanged product updates the product in place — it never creates a new version. |
category_hours |
no | The category's availability window, e.g. Mon-Fri 12:00-16:00. Days are short names (Mon…Sun) as a range and/or comma list (Mon,Wed,Fri, Sat-Sun) — omit them for every day. Times are 24-hour HH:MM; a start after the end wraps past midnight (22:00-02:00). Days without times (Sat-Sun) means all day. One window per category, and every row of a category must carry the same value (or leave all but one blank). Blank = leave unchanged (a new category is always available); write always to explicitly clear the window. |
2. Upload and review the dry run
Import CSV → choose your file → pick a target (a new menu, or add categories to an existing one). Every row is checked and classified:
- Create — a new product will be created.
- Reuse — a product with the same name already exists with identical price/tax/description; it's attached as-is.
- Re-version — the name matches but details differ; a new price/detail version is created (the normal versioned-edit path — historic sales keep the old version). It inherits the product's 86 state and availability windows.
- Error — the row can't be imported; the note says why. Fix the file and re-check.
Nothing is written during the dry run, and the import button stays disabled while any row has an error.
3. Import
The import runs in a single transaction — it either all lands or nothing does. A new menu is created with no channels, so it can't go live by accident; set channels and the schedule from the categories panel when you're ready. Re-uploading the same file is safe: every row simply becomes a Reuse.
Exporting
Every menu has an Export CSV action on its page — the file comes out in exactly this import format (including allergens, available and category_hours), so the loop is: export → bulk-edit in a spreadsheet → re-import. Unchanged rows all come back as Reuse.