POS Product Configuration
Product types
When syncing products to Deliverect, you need to specify the relevant productType value, which is an integer that corresponds to it's intended function. These are defined in the table below;
| Product Type | Integer Value | Integer Value |
|---|---|---|
| Product | A 'top level' item on a menu (can also be grouped within a modifier group or bundle) | 1 |
| Modifier | Options selectable when ordering a product, typically modifications of the product | 2 |
| Modifier Group | A grouping of modifiers (can also group products) | 3 |
| Bundle | Can only contain products which are offered as part of a 'Meal Deal' and which Deliverect will set to zero value. Exception to this is where Overloads are set | 4 |
PLU
The PLU is typically something that's easier for the customer to use, and it should be the same across all locations for the same product. The PLU is what will be used for mapping orders coming from the channels to your integrated POS.
Price
Price is stored as an int with 2 decimal digits, for example, 5 euros is stored as 500.
Price Levels
All Product and Modifier items include a base "price" field. Optionally, additional prices can be defined using "priceLevels" in order to support different pricing for specific ordering channels and menu fulfilment type.
The "priceLevels" object for a product or modifier should include:
- A price level property name which will be it's unique identifier.
- An corresponding integer value defining the price to apply
The price level identifier set must also be defined in a "priceLevels" array, where each entry requires:
"posId"– this is the unique identifier referenced in product and modifier price levels."name"– a descriptive label which will be displayed in channel settings.
When configured as in below example, price levels can be mapped via channel link settings to a specified menu fulfilment type e.g. a 'First Party' channel can have a unique price level set for 'Delivery' , 'Pickup' and 'Eati-in' menus. The mapping process is described in the Price Level guide here. You can verify the configuration by previewing menus and switching between channels.
Example
In the example below, a product will be sold at different prices when correctly mapped on the ordering channel:
{
"products": [
{
"name": "Ginger Beer",
"productType": 1,
"plu": "DRNK-03",
"price": 350,
"priceLevels": {
"TA": 350,
"DL": 400,
"1PO": 300
}
}
],
"priceLevels": [
{
"name": "Takeaway",
"posId": "TA"
},
{
"name": "Delivery",
"posId": "DL"
},
{
"name": "First Party",
"posId": "1PO"
}
]
}Tax
It is important to specify the sales tax rate which applies to any item. The sales tax which applies can be differentiated between the order types of;
- Delivery (
deliveryTax) - Takeaway (
takeawayTax) - Eat-in (
eatInTax)
Tax rates should be stored as an int with 3 decimal digits e.g. 5% would be 5000
It's acceptable to have a 0% tax
{
"productType": 1,
"plu": "GB-02",
"name": "Ginger Beer",
...
"deliveryTax": 5000,
"takeawayTax": 5000,
"eatInTax": 0,Bag Fee
In certain regions, ordering platforms are required to process a specific payment for a bag fee. Deliverect will by default included this fee within the serviceCharge. It is also an option for the POS to sync a bag fee product with a unique PLU, this would need manually set per channel but will ensure the POS receives the bag fee as seperate item in the orders payload.
See guide on setting a bag fee PLU here
Ingredient Groups & Modifier Deltas
An attribute can be set on a modifier group to identify it as an 'Ingredient Group' "isIngredientGroup": true, to indicate that it includes options which will be included by default. When this in place, the order payload will pass only the delta, whereby if a customer removes or adds an option from this group, an attribute "modifierAction" will specify "NO"/"ADD"
This typically applies to Pizza ordering, where kitchen teams will want to review only what differs from the standard toppings included by default in the item.
Default Selection via Scopes
To mark an item as selected by default when offered on specific items only, an attribute "overloads" allows for a defined list of "scopes" . Below, the "Mozzarella" and "Pizza Sauce" are set with a specific combination of product and modidifer group PLUs e.g. "BYOP-00-->>BYOP-TOP"meaning that the only within this combination will the "defaultQuantity":1 apply.
Ingredients without pricing onlyIt is only possible to define items with zero price within modifier groups with the flag
"isIngredientGroup": true
{
"products": [
{
"name": "Build your own Large Pizza",
"productType": 1,
"plu": "BYOP-00",
"subProducts": [
"TOP",
"EXTRAS"
]
},
{
"name": "Toppings",
"plu": "TOP",
"isIngredientGroup": true,
"min": 0,
"max": 3,
"multiMax": 1,
"productType": 3,
"subProducts": [
"SAUCE",
"MOZ",
"CH_F"
]
},
{
"name": "Mozzarella",
"deliveryTax": 1200,
"plu": "MOZ",
"price": 0,
"productType": 2,
"overloads": [
{
"scopes": [
"BYOP-00-->>BYOP-TOP"
],
"defaultQuantity": 1
}
]
},
{
"name": "Pizza Sauce",
"deliveryTax": 1200,
"plu": "SAU",
"price": 0,
"productType": 2,
"overloads": [
{
"scopes": [
"BYOP-00-->>BYOP-TOP"
],
"defaultQuantity": 1
}
]
}
]
}Modifier Delta
When a customer has removed a default topping from an order, the order payload will indicate this as in snippet below "modifierAction": "NO" similarly, if an optional item from the ingredient group is included it will show "modifierAction": "ADD"
{
"items": [
{
"name": "Build your own Large Pizza",
"subItems": [
{
"plu": "E-Mz-O1-",
"name": "Mozzarella",
"modifierAction": "NO"
}
]
}
]
}{
"items": [
{
"name": "Build your own Large Pizza",
"subItems": [
{
"plu": "CH_F",
"name": "Chili Flakes",
"modifierAction": "ADD"
}
]
}
]
}
Only for Default IngredientsFor any mandatory modifier groups e.g. for Pizza, the "Size" and "Crust" or other single-select groups, these should not be set as
isIngredientGroup": trueas these selections need to pass through on the order webhook and no delta logic needs applied.
Overloads
Specific item attributes can be overridden depending on the item or grouping it is offered within.
It's primary purpose is to set context-specific pricing e.g. surcharges applied to combo products to alter the base price normally applied. The same structure can also be applied for other attributes to alter the base values in place.
An overload consists of:
- A
"scopes"array containing one or more PLU identifiers. - One or more override properties e.g.
"price"or"bundlePrice"
{
"overloads": [
{
"scopes": ["PLU-123"],
"<property>": "<override value>"
}
]
}Supported Overload Values
| Property | Description |
|---|---|
price | Standard price override |
bundlePrice | Bundle group specific price override productType:4 |
defaultQuantity | A default quantity of greater or equal to 1 is a "pre-selected" item |
min | Minimum selection quantity allowed |
max | Maximum selection quantity allowed |
multiMax | Maximum quantity of multiple selections of the same item |
name | Display name |
description | Description text |
nameTranslations | Localized names |
descriptionTranslations | Localized descriptions |
imageUrl | Product image |
visible | Visibility flag (enabled/disabled) |
Overloads Pricing Rules
The pricing property for overloads depends on the type of group in which the product is being used:
| Group Type | Override Property |
|---|---|
| Modifier Group (type: 3) | price |
| Bundle Group (type: 4) | bundlePrice |
the example below and also in samples 4 and 5 in the Insert/update products page, you can see both a product and modifier price being set this way.
The "overloads" array contains "scopes" which specify the group(s) in which either a"bundlePrice"(if a bundle group) or "price"(if not a bundle group) can be set differently.
In the first example below, an Avocado with base price 50, can be set to 0 if included in a group "FREE-TOP" and set to 100 if set in a group "XTRA-TOP"
The second example shows the same format for an Ice Cream with a base price 500, which can be set to 0 if included in a group "FREE-DESS" and 450 if set in a group "ADD-ON"it used the bundlePrice attribute as the group is not a modifier group (productType:3) but bundle (productType:4)
Overloads Examples - Price Overrides
The modifier in the first example has a base price of 50, but when chosen within the modifier group FREE-TOP, it's price will be set at 0 and when chosen within a product with PLU: BRGR it's price is 450
Similarly, in the second example, the base price of the Ice Cream, 500 becomes 0 when chosen in a bundle group with PLU "FREE-DESS" and 450 when chosen within a combo product with PLU: BRGR_COMBO
Overloads Examples - Default Quantity
In the third example, the Chicken Tenders is set with "defaultQuantity": 1 and will pre-selected only when displayed within a modifier group with PLU: CHK_MEAL
{
"productType": 2,
"plu": "AVO",
"price": 50,
"name": "Avocado",
"overloads": [
{
"scopes": [
"FREE-TOP"
],
"price": 0
},
{
"scopes": [
BRGR"
],
"price": 100
}
]
}{
"productType": 1,
"plu": "IC",
"price": 500,
"name": "Ice Cream",
"overloads": [
{
"scopes": [
"FREE-DESS"
],
"bundlePrice": 0
},
{
"scopes": [
"BRGR_COMBO"
],
"price": 450
}
]
}{
"productType": 1,
"plu": "PROD-1",
"price": 500,
"name": "Chicken Tenders",
"overloads": [
{
"scopes": [
"CHK_MEAL"
],
"defaultQuantity": 1
}
]
}Images
The image URL you provide here is cached and put behind a CDN. Images are cached on access for 24 hours. Channels will download the images and also cache them. Depending on the channel, images can/will be resized. Deliverect supports images of up to 16.8 megapixels in size.
Categories
A category is a way to organise products into a section to be referenced when building a menu. Products can be in one or more categories denoted by an array of posCategoryIds. It's important to have at least one category per product.
Overrides
Customers are able to overwrite certain details of products within the menu builder in Deliverect, including;
- Names
- Descriptions
- Prices
- Images
*Everything that is not overwritten in Deliverect can be updated via this endpoint
Modifier Groups
The first example below represents a simple Product (productType:1) with three modifier groups attached (productType:3) where each modifier group contains an amount of modifiers (productType:2)
Typical use case: This structure would support standard modifications to a product e.g. required modifiers of 'Rare', 'Medium' or 'Well Done' would be applied to a Steak product.

{
"products": [
{
"productType": 1,
"plu": "STK-01",
"price": 1500,
"name": "Delicious Steak Frites",
"deliveryTax": 9000,
"takeawayTax": 9000,
"eatInTax": 9000,
"posCategoryIds": [
"STK"
],
"description": "Delicious Steak Frites",
"subProducts": [
"MOD"
]
},
{
"productType": 3,
"plu": "MOD",
"name": "Add a side",
"imageUrl": "",
"description": "Pizza made for cheese fanatics",
"subProducts": [
"SI-01",
"SI-02",
"SI-03"
],
"min": 0,
"max": 0,
"multiMax": 3
},
{
"productType": 2,
"plu": "SI-01",
"price": 0,
"name": "Fries",
"posCategoryIds": [
"SD"
],
"imageUrl": "",
"description": "Fries",
"deliveryTax": 9000,
"takeawayTax": 9000,
"eatInTax": 9000
},
{
"productType": 2,
"plu": "SI-02",
"price": 200,
"name": "Salad",
"kitchenName": "",
"posCategoryIds": [
"SD"
],
"imageUrl": "",
"description": "Salad",
"deliveryTax": 9000,
"takeawayTax": 9000,
"eatInTax": 9000
},
{
"productType": 2,
"plu": "SI-03",
"price": 100,
"name": "Mashed Potato",
"kitchenName": "Mash",
"posProductId": "POS-ID-014",
"posCategoryIds": [
"SD"
],
"imageUrl": "",
"description": "Mashed Potato",
"deliveryTax": 9000,
"takeawayTax": 9000,
"eatInTax": 9000
}
],
"categories": [
{
"name": "Steaks",
"posCategoryId": "STK"
},
{
"name": "Sides",
"posCategoryId": "SD"
}
]
}This same structure can also be applied to group together products (productType:1) within modifier groups (productType:3)
Typical use case: This structure is often applied as an "Upsell" where additional optional priced items are offered alongside a product.

{
"productType": 1,
"plu": "STK-01",
"price": 1500,
"name": "Delicious Steak Frites",
"deliveryTax": 9000,
"takeawayTax": 9000,
"eatInTax": 9000,
"posCategoryIds": [
"STK"
],
"description": "Delicious Steak Frites",
"subProducts": [
"Drink"
]
},
{
"productType": 3,
"plu": "Drink",
"name": "Add a Drink",
"imageUrl": "",
"description": "Select a drink with your meal",
"subProducts": [
"DR-01",
"DR-02",
"DR-03"
],
"min": 0,
"max": 0,
"multiMax": 3
},
{
"productType": 1,
"plu": "DR-01",
"price": 0,
"name": "Coke",
"posCategoryIds": [
"DR"
],
"imageUrl": "",
"description": "Fries",
"deliveryTax": 9000,
"takeawayTax": 9000,
"eatInTax": 9000
},
{
"productType": 1,
"plu": "DR-02",
"price": 200,
"name": "Ginger Beer",
"posCategoryIds": [
"DR"
],
"imageUrl": "",
"description": "Salad",
"deliveryTax": 9000,
"takeawayTax": 9000,
"eatInTax": 9000
},
{
"productType": 1,
"plu": "DR-03",
"price": 100,
"name": "Fanta",
"posProductId": "POS-ID-014",
"posCategoryIds": [
"DR"
],
"imageUrl": "",
"description": "Fanta ",
"deliveryTax": 9000,
"takeawayTax": 9000,
"eatInTax": 9000
}
],
"categories": [
{
"name": "Steaks",
"posCategoryId": "STK"
},
{
"name": "Drinks",
"posCategoryId": "DR"
}
]
}Item Rules
Individual items can have rules set against them to control how they can be ordered online
| Rule | Purpose | Type |
|---|---|---|
multiMax | To restrict the number of products that can be sold within one order e.g. pharmaceuticals. You can achieve this by adding the attribute "multiMax" e.g. "multiMax": 1, prevents more than one of the items being added to the basket. | Integer |
defaultQuantity | This attribute makes a modifier preselected by default, where a value of 1 is equivalent to a pre-selected item. Most channels can handle a pre-selection, but not with a pre-selected quantity of more than 1 | Integer |
Item Group Rules
Both Modifier Groups and Bundles allow certain ordering "rules" to be applied as follows;
| Rule | Purpose | Type |
|---|---|---|
min | Setting a minimum value to a group of options e.g. 0would be equivalent to 'optional'and1or more would be 'required' | Integer |
max | Setting a maximum value limits how many items in a group can be ordered | Integer |
multiMax | Setting the attribute A value of '2' for example, means that each item in a group can be selected at most 2 times. The selection of a single item will still be limited by the overall | Integer |
Meal Deals
In the payload examples on this page, shown on the right hand side, various product structures are depicted including combos and meal deals.
These examples use the structure below, where products are linked together using the subProducts field.
Meal Deal / Combo Structure
A meal deal or combo will typically have a set price, where a grouping of a 'Bundle' can contain products which normally have a price, but as part of a bundle will be zero-priced.
The diagram below shows that it is possible to contain the zero-priced 'Bundle' options as well as 'Modifier Groups' containing priced items.
Important Attribute for Combos/Meal DealsPlease ensure the attribute
"isCombo": trueis set on the main product"productType": 1and linked to a Bundle groups"productType": 4,as certain channels need this flag and Bundle groups to display these options correctly
Bundles cannot be nested under a sub-product and must be at the top level of options.

The structure to form bundles could be as follows:
- Combo product
Type:1 - Bundle
Type:4- Product
Type:1- Modifier group
Type:3- Modifier
Type:2
- Modifier
- Modifier group
- Product
Nested Modifiers
A product configuration can include a sub-group of options to be selected. These options themselves can also contain their own sub-groups, this is reffered to as 'Nested Modifiers'.

Meal Deal with 'Upsell'
In the Meal Deal with upsell (example 3) we have a modifier group in addition to the bundles. This allows for Fries to be ordered which are not included as part of the deal and the customer will be charged accordingly. This is referred to as an 'upsell', which can be modifier groups containing products or modifiers.
It is also possible to construct combo products as follows:
- Combo product
Type:1 - Modifier group
Type:3- Modifier
Type:2- Modifier group
Type:3- Modifier
Type:2
- Modifier
- Modifier group
- Modifier
Click here to see examples of how orders with these meal deal examples are sent to your POS in an order.
Variants
A variant in a menu allows customers to choose from different versions of a product, such as pizza sizes or beverage flavors. The variant product displays the lowest price, then allows the customer to choose from a list of variations of the product by showing additional costs for selecting larger sizes, ensuring clear and transparent pricing for customization.
"products": [
{
"productType": 1,
"plu": "VAR-PROD-1",
"price": 0,
...
"isVariant": true,
...
"subProducts": [
"MG-VAR-1"
]
},
{
"productType": 3,
"plu": "MG-VAR-1",
"name": "How many pieces?",
"posProductId": "POS-002",
"isVariantGroup": true,
"subProducts": [
"VAR-1",
"VAR-2",
"VAR-3"
]Follow the "Example 6 - Variant products" on the insert/update products endpoint.
Chicken tenders: €8
3 pieces: + €0
6 pieces: + €3
9 pieces: + €5.50

For example, Chicken Tenders start at €8. If a customer selects 3 pieces, the price remains €8. If they choose 6 pieces, an additional €3 is added, making the total €11. For 9 pieces, an extra €5.50 is added, bringing the total to €13.50.
Auto Apply
There can be a use case where products ordered online should be received with a pre-defined set of sub products applied. This is not the same as items being pre-selected in the menu interface via defaultQuantity, but is a mechanism for specific items to be auto-applied (by Deliverect) following a completed order.
This is shown in the example below, where the Parsley Garnish and Melted Butter are within a modifier group 'Garnishes' which is set to apply these items automatically when the Steak Frites is ordered.
Note that "defaultQuantity": 3 is shown below and defines how many of the item should be auto-applied to the order. The "sortOrder" attribute allows a 'stepped' order of the auto-applied items to appear, where 0 is the first item to be listed.
'NB: Neither the channel platform or end-consumer will see the auto-applied items, and as such there can be no price associated with them. If de-selection of pre-set items or charging for them is a requirement,"defaultQuantity" can be used without "autoApply" (See 'Item Rules').
"autoApply": [
{
"plu": "PR1"
},
{
"plu": "PR2"
}
],{
"productType": 2,
"plu": "PR1",
"price": 0,
"name": "Parsley",
"posProductId": "PA_POS-0023",
"posCategoryIds": "",
"imageUrl": "",
"description": "",
"deliveryTax": 0,
"takeawayTax": 0,
"subProducts": [],
"defaultQuantity": 3,
"sortOrder": 1
}Translations
Translations are supported for all product types and both the name and description can be set with a translated value. Additionally, category names and descriptions can be translated. can be provided in the JSON. A base name is always required but translations are optional.
See examples of the nested object for translations below, where the property key is the language tag and the value is the translation itself.
See all language tags supported via the link below;
Translation Examples
{
"productType": 1,
"plu": "MEAT-02",
"price": 200,
"name": "Chicken",
"nameTranslations": {
"ar": "دجاج",
"en": "Chicken",
"es": "Pollo",
"nl": "Kip"
},
"description": "Grilled chicken",
"descriptionTranslations": {
"ar": "دجاج مشوي",
"en": "Grilled chicken.",
"es": "Pollo asado.",
"nl": "Gegrilde kip."
}
}{
"posCategoryId": "B2",
"name": "Burgers",
"nameTranslations": {
"ar": "برجر",
"pt": "Hambúrgueres",
"es": "Hamburguesas",
"zh": "汉堡"
},
"imageUrl": "https://storage.googleapis.com/ikona-bucket-production/images/5be9fe94c6489f0001b2fe57/174466-666abfd750c486d4c3a2d5a9.jpg",
"description": "Our Burgers are made with 100% all-natural Angus beef, responsibly raised and cooked to order",
"descriptionTranslations": {
"ar": "برجراتنا مصنوعة من لحم أنجوس طبيعي 100%، تم تربيتها بمسؤولية ويتم طهيها حسب الطلب",
"pt": "Nossos hambúrgueres são feitos com 100% de carne Angus totalmente natural, criada de forma responsável e cozida a pedido",
"es": "Nuestras hamburguesas están hechas con carne Angus 100% natural, criada de manera responsable y cocinada a pedido",
"zh": "我们的汉堡采用100%天然安格斯牛肉制作,经过负责任的养殖,并按订单烹制"
}
}Product visibility
A product can be marked as invisible (disabled) by setting visible property to false. After this action the product will be hidden all menus where it was used and will not be pushed to channels until it marked as visible again.
For more granularity on "visible" status, this can be applied at a channel level, see guide [here](status at a channel level,)
{
"productType": 1,
"plu": "SI-01",
"price": 100,
"name": "Fries",
"visible": false
}Product tags: consumable types and allergens
A product can have one or more product tags. These are are contained inside productTags
In below example snippet, 104 and 109 are values representing 'eggs' and 'peanuts'
{
"productType": 1,
"plu": "P-SATE",
"price": 450,
"name": "Chicken Sate",
...
"productTags": [
104,
110
]
},See link below for a complete list of tags available;
Nutritional Information and Supplemental Info
A product can be set with nutritional and supplemental information e.g. packaging, additives etc and certain attributes shown in the link below will be legally required in some regions;
Calories
Calories can be sent as in the example shown below;
| Parameter | Meaning |
|---|---|
calories | This is the base calorie amount, where a maximum calories is set, this should be interpreted as the 'minimum' |
caloriesRangeHigh | The maximum calorie amount of an item |
"products": [
{
"productType": 1,
"plu": "PR03",
"price": 900,
"name": "Cheese Lovers Pizza",
...
"calories": 500,
"caloriesRangeHigh": 750
},
...
]
},