Product Management
Products are organized in a three-level hierarchy: Group → Department → PLU (product). Tags provide an additional cross-cutting grouping mechanism, and menus bundle products into meals or combos.
Hierarchy Overview
Section titled “Hierarchy Overview”Group (grp)├── Department (dpt)│ ├── PLU (product) — type 1: Sales│ ├── PLU (product) — type 2: Ingredient│ └── PLU (product) — type 8: Prepared└── Department (dpt) ├── PLU (product) └── PLU (product)Each product belongs to exactly one department, and each department belongs to exactly one group. All three entities are scoped to a company.
Group (grp)
Section titled “Group (grp)”Groups are the top-level product category.
| Field | Type | Description |
|---|---|---|
grp_num | int | Unique group number |
name | string | Group name |
data.sales_grp | boolean | Contains sales departments |
data.stock_grp | boolean | Contains stock/inventory departments |
data.image_url | string | Image for menu exports |
data.sort_order | number | Display order in menu exports |
Department (dpt)
Section titled “Department (dpt)”Departments sit between groups and products.
| Field | Type | Description |
|---|---|---|
dpt_num | number | Unique department number |
grp_id | id | Parent group reference |
name | string | Department name |
data.sales_dpt | boolean | Sales department |
data.stock_dpt | boolean | Stock/inventory department |
data.default_tax | number | Default tax rate for new products in this department |
data.color | string | Button color on POS |
data.image_url | string | Image for menu exports |
data.sort_order | number | Display order in menu exports |
Product (plu)
Section titled “Product (plu)”The PLU is the core product entity.
| Field | Type | Description |
|---|---|---|
productid | string | Unique product number (often auto-generated from department template) |
name | string | Product name (translatable) |
receipt_name | string | Shortened name for receipts (translatable) |
type | int | Product type (see below) |
base_price | number | Base selling price (tax-inclusive) |
dpt_id | id | Parent department |
tax_id | id | Tax rate reference |
image_id | string | Primary product image (attachment ID) |
memo | string | Free text description (translatable) |
Product Types
Section titled “Product Types”| Type | Name | Description |
|---|---|---|
| 1 | Sales | Standard sellable product |
| 2 | Ingredient | Raw material / ingredient for recipes |
| 3 | Service | Service item |
| 4 | Wastage | Wastage tracking item |
| 5 | Reporting | Reporting-only item |
| 6 | Stock | Stock management item |
| 8 | Prepared | Prepared/composite product (has recipe) |
Key Data Fields
Section titled “Key Data Fields”Products carry extensive configuration in plu.data:
flags— Boolean toggles:askprice,kitchenprinter,nosell,no_discount,modifier,giftcard,scale,alcohol, etc.barcode/barcodes— Main barcode and additional barcodes with optional custom quantity/pricerecipe— Ingredient list for composite products (type 1 & 8), each with multiplier, price, and tax referencestock_units— Multiple units of measure (pcs, weight, liquid) with stock quantities and supplier infosupply— Supplier information for orderingallergens— EU 14 allergen flags (cereals_gluten, crustaceans, eggs, fish, peanuts, soybeans, milk, nuts, celery, mustard, sesame, sulphites, lupin, molluscs)nutrition— Nutritional information (energy, fats, carbohydrates, protein, salt, vitamins, etc.)cost_price— Purchase price (tax-free), used for margin calculationssales_channels— Which sales channels this product is available in
Tags — Alternative Grouping
Section titled “Tags — Alternative Grouping”The plu.data.tags field (string array) provides a flexible grouping mechanism that is independent of the Group →
Department hierarchy.
Tags are defined at the company level (company.data.default_tags) and can be freely assigned to any product regardless
of its department. This enables cross-cutting categorizations such as:
- Dietary:
vegan,gluten-free,lactose-free - Menu sections:
breakfast,lunch,dessert - Channels:
app-menu,takeaway - Promotions:
happy-hour,seasonal
Tags are used in several places:
- Menu item selection — A menu item can select products by tag (via
taglist) instead of listing individual PLU IDs - Filtering and reporting — Filter product lists by tag in the management UI
- External integrations — Tags can drive which products appear in online ordering or delivery platforms
Menus — Meals & Combos
Section titled “Menus — Meals & Combos”A menu bundles multiple product selections into a single sellable unit — for example a meal deal or a combo.
Structure
Section titled “Structure”A menu contains an array of menu items, each defining one selection step:
| Field | Type | Description |
|---|---|---|
type | enum | Display type: POPUP, LIST, FOLDABLE, LAYOUT, PICKER, HIDDEN |
plulist | guid[] | Specific products to choose from |
dptlist | guid[] | Select from all products in these departments |
taglist | string[] | Select from products matching these tags |
optional | boolean | Whether the selection can be skipped |
min_qty / max_qty | number | Quantity constraints |
default_plu | guid | Pre-selected product |
pricing | plu_pricing | Override pricing for this step |
price_level | guid | Use an alternate price level |
group_price | boolean | Include this item’s price in the main product |
Example: Hamburger Meal
Section titled “Example: Hamburger Meal”A “Hamburger Meal” menu with three steps:
Menu: Hamburger Meal├── Item 1: Burger (required)│ plulist: [Classic Burger, Cheese Burger, Veggie Burger]│ optional: false, min_qty: 1, max_qty: 1│├── Item 2: Side (required)│ taglist: ["sides"]│ optional: false, min_qty: 1, max_qty: 1│ pricing: { type: "PRICE", amount: 0 } ← included in meal price│└── Item 3: Drink (optional) dptlist: [Drinks department] optional: true, min_qty: 0, max_qty: 1 pricing: { type: "PRICE", amount: 2.50 } ← fixed add-on priceProduct selection within a menu item can use any combination of plulist, dptlist, and taglist. The pricing
override on each item controls whether the component is included in the base price or charged separately.
The menu’s type field controls the overall UI flow: SINGLE for a simple combo, WIZARD for a step-by-step builder.
Pricing
Section titled “Pricing”Pricing entries define named price levels that can be assigned to products.
| Field | Type | Description |
|---|---|---|
name | string | Price level name (e.g. “Self-Service”, “Happy Hour”, “VIP”) |
data.type | enum | baseprice, price, discount, percent, purchaseprice |
data.shortname | string | Short display name |
data.set_taxtype | boolean | Whether this price level overrides the tax rate |
data.taxtype | guid | Tax rate override (when set_taxtype is true) |
Each product stores its price level values in plu.data.prices, keyed by the pricing entry’s GUID:
{ "data": { "prices": { "pricing-guid-1": { "type": "PRICE", "amount": 8.50 }, "pricing-guid-2": { "type": "PERCENT", "amount": 90 } } }}Pricing Types
Section titled “Pricing Types”| Type | Effect |
|---|---|
baseprice | Use the product’s base price (no change) |
price | Fixed alternative price |
discount | Subtract amount from base price |
percent | Percentage of base price (e.g. 90 = 90% of base price) |
purchaseprice | Cost/purchase price (for stock valuation) |
Common Use Cases
Section titled “Common Use Cases”- Self-service channel — A “Self-Service” price level with lower prices, assigned to self-service POS terminals
- Customer-specific pricing — A “VIP” or “Wholesale” price level assigned to customer groups
- Happy hour — A “Happy Hour” price level with discounted prices, activated by time-based rules on the POS
- POS-selectable — Cashier manually selects a price level on the terminal (e.g. for staff meals)
Price levels are subscribed per POS terminal via pos.data.subscriptions, so each terminal can offer different price
levels.
Tax Rates
Section titled “Tax Rates”The tax data is shared across all companies and cannot be edited through the API — it is maintained centrally.
Products reference a tax rate via plu.tax_id. The current Finnish VAT rates are:
| Name | Rate | tax_num | Valid From |
|---|---|---|---|
| ALV 0% | 0% | 4 | 1990-01-01 |
| ALV 10% | 10% | 3 | 2013-01-01 |
| ALV 13.5% | 13.5% | 2 | 2025-12-01 |
| ALV 25.5% | 25.5% | 1 | 2024-09-01 |
Relationships Summary
Section titled “Relationships Summary”Tax ←──────── PLU (product) ──────→ Department ──────→ Group │ ├── data.tags[] (cross-cutting grouping) ├── data.prices{} (pricing per price level) ├── data.recipe[] (ingredient links to other PLUs) ├── data.sales_channels[] (channel availability) └── data.menu_items[] (menu associations)
Menu └── items[] ──→ selects PLUs by plulist / dptlist / taglist
Pricing ──→ referenced in plu.data.prices{} and menu item overrides