Guidelines
An article with full guidelines on how to make your menu standout is available, below is an extract adapted and updated for API users.
Cover photo1
This should showcase your brand and encourage customers to visit your restaurant page.
Accepted formats: JPEG
, PNG
. At least 1920x1080
pixels, 16:9
aspect ratio, Max Size upto 18 MB
.
Menu description2
This sits at the top of the menu page and explains what makes your restaurant different. We recommend telling the story of your brand and explaining why it was created.
Accepted formats: Up to 500 characters - ideally between 200-245 characters.
Category names3
The titles of the sections of your menu. This should help customers easily navigate your menu and clearly understand each section.
Accepted formats: Between 3-120 characters.
Category descriptions4
It should explain why these set of items are grouped together as well as highlight the key ingredients and tastes associated with the category.
Accepted formats: Between 3-255 characters - ideally between 200-245 characters.
Item names5
The titles of your dishes.
Accepted formats: 2-120 characters, ideally below 60 characters.
Item descriptions6
It should give the customer all the information they need to understand the dish, from ingredients to allergens.
Accepted formats: Up to 500 characters, but only the first 60 characters will be visible on screen on the menu page (the rest is visible when click on the item)
Item photos7
These will be photos of specific menu items. Customers will see these photos when they visit your restaurant page. Specific photos of each item on your menu makes it as easy as possible for customers to decide what to order.
Accepted formats: JPEG
, PNG
. 1920x1080
pixels 16:9
aspect ratio.
Age restrictions
Thecontains_alcohol
field should be used for any age restricted item identification (whether it’s alcohol, tobacco, vapes, or any other product) and will trigger an ID check at the point of delivery when marked astrue
. Examples of age restricted items include: lighters containing butane, cbd, vapes, alcohol, 18+ DVDs.
Item allergens
Help consumers with allergies by providing an up-to-date structure description of any allergens that may be present in your dishes.
The special code no_allergens
means that the item has none of the known allergens on the list. In order to send "information unavailable" just provide an empty array.
Valid allergen values by country:
Countries | Valid allergens value |
---|---|
UK, IE, FR, IT, BE, AE | "no_allergens", "celery", "crustaceans", "eggs", "fish", "gluten_wheat", "gluten_rye", "gluten_barley", "gluten_oats", "lupin", "milk", "molluscs", "mustard", "nuts_almond", "nuts_hazelnut", "nuts_walnut", "nuts_cashew_nut", "nuts_pecan_nut", "nuts_brazil_nut", "nuts_pistachio_nut", "nuts_macadamia_or_queensland_nut", "peanuts", "sesame_seeds", "soybeans", "sulphur_dioxide_sulphites" |
KW, QA | "no_allergens", "celery", "crustaceans", "eggs", "fish", "gluten_wheat", "gluten_rye", "gluten_barley", "gluten_oats", "milk", "mustard", "nuts_almond", "nuts_hazelnut", "nuts_walnut", "nuts_cashew_nut", "nuts_pecan_nut", "nuts_brazil_nut", "nuts_pistachio_nut", "nuts_macadamia_or_queensland_nut", "peanuts", "sesame_seeds", "soybeans", "sulphur_dioxide_sulphites" |
SG, HK | "no_allergens", "crustaceans", "eggs", "fish", "gluten_wheat", "gluten_barley", "gluten_oats", "milk", "nuts_almond", "nuts_hazelnut", "nuts_walnut", "nuts_cashew_nut", "nuts_pecan_nut", "nuts_brazil_nut", "nuts_pistachio_nut", "nuts_macadamia_or_queensland_nut", "peanuts", "soybeans", "sulphur_dioxide_sulphites" |
Item classifications information
If an item falls into any of the applicable classifications from the list below, it should be set where relevant. This information is used to ensure marketing and/or quantity restrictions are applied in line with local legislation and enables better identification of highly regulated items. Please note that this must be used in addition to thecontains_alcohol
field where items require an age verification check at delivery.
Currently supported classifications are:
Country | Classification | Description |
---|---|---|
All | "early_stage_infant_formula" | This includes all infant formula products, excluding follow on formula products |
All | "pharmaceuticals_aspirin" | Any product that is exclusively or contains aspirin |
All | "pharmaceuticals_ibuprofen" | Any product that is exclusively or contains ibuprofen |
All | "pharmaceuticals_paracetamol" | Any product that is exclusively or contains paracetamol |
UK, IE, BE, IT, FR, HK, SG | "alcohol_product" | Any product containing alcohol - age restrictions apply (18+) |
UK, IE, KW | "vape_product" | Any e-cigarette or ‘vape’ product - age restrictions apply (18+). For KWT, age restrictions are 21+ |
UK, IE, KW | "tobacco_product" | Any product containing tobacco - age restrictions apply (18+). For KWT, age restrictions are 21+ |
UK | "cbd_product" | Any product containing CBD - age restrictions apply (18+) |
AE, KW, QA | "non_muslim" | Any product classified as non-muslim |
Item dietary information
Help consumers with dietary information by providing an up-to-date description of any dietary category (or categories) a specific item complies with.
This information helps customers to easily identify the items that more closely match with their requirements
Currently, the supported dietary codes per market are:
Country | Valid dietary information value |
---|---|
UK, IE | "dairy_free" ,"gluten_free" ,"halal" ,"keto" ,"paleo" ,"plant_based" ,"vegan" ,"vegetarian" |
BE, IT | "dairy_free" ,"gluten_free" ,"halal" ,"vegan" ,"vegetarian" |
FR, HK, SG, AE, QT, KW | "dairy_free" ,"gluten_free" ,"vegan" ,"vegetarian" |
Any invalid values entered in this field will not be shown to consumers.
Item nutritional info
Calories
For Deliveroo menus, both top-level menu items, and items that are only available as modifier choices can have calorie information attributed to them via a specificenergy_kcal
field (present on menu.items[].nutritional_info
). This information will be displayed clearly and prominently at the ‘point of choice’ for the customer on Deliveroo menu pages.
From the energy_kcal
field on the nutritional information object, we will only display the nutritional_info.energy_kcal.high
field to customers, however this may change in the future.
In the case of mapping a single value, rather than a range, both nutritional_info.energy_kcal.high
and nutritional_info.energy_kcal.low
should be set to the same value.
To remove calorie information from an item, or signify that an Item does not have calorie information set nutritional_info.energy_kcal
to null, when an Item is configured like this, no calorie value will be shown at all.
Additionally, setting the whole nutritional_info
field to null will also have the same effect.
Barcodes
Barcodes allows you to assign multiple barcodes to a menu item, up to a maximum of 10 barcodes per item. A barcode should not contain any spaces and should only contain numbers. The following barcode formats are accepted: EAN-8, UPC-A, EAN-12, EAN-13, GTIN-14.
All barcodes for a menu item should correspond to the correct pack size for that item. For example, a barcode for a singular item should not be added to the barcodes for a 6-pack of the same item.
Bundles
Bundle structure
- All items directly nested in top level item(bundle) must be of type ITEM (items visible on the menu to customers)
- All modifiers directly nested in top level item must be of type bundle-item
- Each bundle must have at least one way of being constructed without any additional cost (eg. at least 1 item the consumer can select from each section that is included within the base price of the bundle)
- The bundle cannot ever be more expensive than the same items purchased individually outside of the bundle. To ensure this, even in the cheapest possible configuration of the bundle (for each section, take the cheapest item multiplied by the minimum number of times it can be selected), the bundle should cost at most as much as the items sold outside of the bundle, i.e. bundle discount cannot be negative.
Basic Burger - £9 (item A of type ITEM)
Classic Burger - £10 (item B of type ITEM)
Premium Burger - £11 (item C of type ITEM)
Deluxe Burger - £13 (item D of type ITEM)
Basic fries - £4.50 (item E of type ITEM)
Loaded fries - £6 (item F of type ITEM)
Burger Bundle - <= £13.50 (item of type BUNDLE). It has to cost at most £13.50 because the
cheapest burger is item A worth £9, and the cheapest fries are £4.50 (min of "Choose up to 2 sides" is 1).
Choose your main (modifier of type bundle_item)
Basic Burger - £0 (item A with price override)
Classic Burger - £0 (item B with price override)
Premium Burger - £2 (item C with price override)
Deluxe Burger - £4 (item D with price override)
Choose up to 2 sides (modifier of type bundle_item(min=1 max=2), i.e. where the customer can order 1 or 2 fries)
Basic fries - £0 (item E with price override)
Loaded fries - £1.50 (item F with price override)
- Premium options offered as part of a bundle should not cost more than the difference between the item price when sold outside the bundle and the cheapest item included in the same section. For example:
Basic Burger - £9 (item A of type ITEM)
Classic Burger - £10 (item B of type ITEM)
Premium Burger - £11 (item C of type ITEM)
Deluxe Burger - £13 (item D of type ITEM)
Burger Bundle - £30 (item of type BUNDLE)
Mains (modifier of type bundle_item)
Basic Burger - £0 (item A with price override)
Classic Burger - £0 (item B with price override)
Premium Burger - \<= £2 (item C with price override)
Deluxe Burger - \<= £4 (item D with price override)
Sides, Drinks, etc (modifiers of type bundle_item)
Bundle restrictions
- You recognise and agree that you are fully responsible for ensuring that your offer and its characteristics comply with all applicable laws, regulations and advertising guidance in your jurisdiction.
- For legal reasons, bundles cannot include vice items (Tobacco, Vapes, CBD, Medication and healthcare products, Alcohol) or any other items listed in Deliveroo’s Restricted Items Policy (or the equivalent policy for your country) from time-to-time.
Bundle behaviour
- Upsell items within bundles: If a bundle contains items that contain optional modifiers of type "upsell-existing-items", those upsell modifiers will not be shown to the customer. This is to prevent a confusing experience where, using the above Burger Bundle example, the customer may have the option to add sides and drinks from the Premium Burger (at an additional cost), but also from the bundle (at potentially no additional cost). We encourage partners to label upsell items with the new modifier type “"upsell-existing-items" to prevent this poor user experience. We cannot prevent mandatory modifiers of type "upsell-existing-items" from being visible in the consumer experience within bundles, so this may still cause a confusing user experience if you include items with these types of modifiers in bundles.
- Bundle-item modifier ranges: Bundles are designed so that the customer must select a set quantity of items from each section of the bundle. For modifiers of type "bundle-item" you can put a range for the quantity, however, the customer will only see the maximum of the range and will also need to select the maximum number of items of the range to check out. (Eg. if the "bundle-item" modifier has a range of min=3 and max=5 items the customer will need to choose 5 items). Additionally the base price validation as explained in point 4 of the bundle structure section will be done on the minimum of the range, so it makes most sense when setting up a bundle to ensure the min and max values are equal so that the base price validation is based on the same quantity of items as the consumer will need to select.
- Layers of nested modifiers: Bundles can have up to 3 layers or nested modifiers, which means you should be able to include your existing menu items which can have at most 2 layers of nested modifiers.
- Limitation for items within bundles which have modifiers: If an item included in a bundle has modifiers, and can be chosen more than once, this will cause an error for consumers and they won’t be able to check-out. This is a temporary limitation which already exists today. When you’re including items in your bundles that have modifiers and you want the consumer to be able to select more than 1 of that item, you should keep the current behaviour, as in the example below:
Burgers Bundle - £30 (item of type BUNDLE)
Choose your first Main (modifier of type bundle_item)
Basic Burger - £0 (item A with price override)
*any customisation options*
Classic Burger - £0 (item B with price override)
*any customisation options*
Choose your second Main (modifier of type bundle_item)
Basic Burger - £0 (item A with price override)
*any customisation options*
Classic Burger - £0 (item B with price override)
*any customisation options*
Sides, Drinks, etc (modifiers of type bundle_item)
Modifiers
Modifier type
Please provide the modifier type for all your modifications, whenever available. It will help us improve receipts accuracy and detail each item, thus improving order accuracy, reducing missing items, which will lead to less refunds requested.
Type | Meaning |
---|---|
"up-sell-existing-items" | An existing main menu item sold alongside a main item, e.g coca-cola |
"remove-ingredient" | Removing an ingredient from an item, e.g remove egg |
"add-ingredient" | Adding an additional ingredient to an item, e.g add tomatoes |
"cooking-instruction" | Cooking instructions on how to prepare the item, e.g medium rare |
"size-modification" | A choice of size for the item in question, e.g small. |
"product-variation" | A variation of the product itself, e.g. brioche bun or gluten free. |
"gift-wrap" | Item requires gift wrapping. |
"bundle-item" | Existing menu item sold as part of a bundle. |
"add-separate-condiment" | Add a separate condiment to the item, e.g. ketchup sachet. |
Scheduled menus
Scheduled menus allow you to set which categories of items should appear to customers on a schedule. In order to drive this experience, you’ll need to utilise the menu.mealtimes.schedule
object within your menu payload (see sidebar).
Keep in mind that day_of_week
equal to 0 indicates Monday.
{
"schedule": [
{
"day_of_week": 0,
"time_periods": [
{
"start": "00:00:00",
"end": "10:29:00"
}
]
},
{
"day_of_week": 1,
"time_periods": [
{
"start": "00:00:00",
"end": "10:29:00"
}
]
},
{
"day_of_week": 2,
"time_periods": [
{
"start": "00:00:00",
"end": "10:29:00"
}
]
},
{
"day_of_week": 3,
"time_periods": [
{
"start": "00:00:00",
"end": "10:29:00"
}
]
},
{
"day_of_week": 4,
"time_periods": [
{
"start": "00:00:00",
"end": "10:29:00"
}
]
},
{
"day_of_week": 5,
"time_periods": [
{
"start": "00:00:00",
"end": "10:29:00"
}
]
},
{
"day_of_week": 6,
"time_periods": [
{
"start": "00:00:00",
"end": "10:29:00"
}
]
}
]
}
Mealtime Images
A “hero” image is the image that customers see for your shop and menu page when browsing the consumer app. You can configure an image for each mealtime (i.e. an image url for each mealtime in your menu).
When multiple hero images are provided, customers will see a different image for your shop and menu page when browsing the consumer app depending on which mealtime is active.
Mealtime Schedules
Two options are available for configuring schedules. The options are detailed below.
24H/7D Coverage
The provided schedules must cover a 7D/24H period. This is to ensure that if customers are browsing a menu outside of opening hours, they still see a menu. Consider the following hours:
- Breakfast: 00:00 - 10:29
- Lunch: 10:30 - 13:59
- Dinner: 14:00 - 23:59
Customers browsing in the early hours in the morning (4-6AM) would see the breakfast menu. Users browsing outside of the opening hours of the store would still see the configured mealtime. If it is not possible to configure schedules for all days+hours of the week, partners should explore the option below.
Default Mealtime
A default mealtime is a mealtime without any schedules associated. Menu API - Scheduled Menus should be either null or an empty collection. This will be recognised as the “default” mealtime.
A default mealtime is one that shows when there are no other active mealtimes by schedule. Consider a single “breakfast” mealtime in addition to a default:
- Breakfast: 08:00 - 10:29
- All Day - no schedule
During the breakfast hours, the breakfast mealtime will be shown. Outside these hours, given no other mealtime is active, the default will be shown.
This gives partners the ability to only configure a single specific mealtime and use a fallback at all other times of the day without increased scheduling complexity.
Schedule Rules
Scheduled start and end times must not have the same start and end time, e.g. a mealtime ends at 10:29 and another starts at 10:30. The next mealtime must start at 10:30. Schedules must not overlap, a single mealtime may only be active at a given time. If using default mealtimes, only a single mealtime must be present. Schedules that do not meet the above requirements will cause the menu request to be rejected (400 - Bad Request).
Category/Item Duplication
Partners should avoid duplicating categories, items and modifiers across mealtimes. The correct usage is to use the same category in multiple mealtimes (if required), and items within multiple categories.
Do not create duplicate items and categories unless the items in the category differ, or some part of the item differs.
If the items are not unique by their name+price (excluding overrides), the menu request will be rejected (400 - Bad Request).
Examples:
- Do not create duplicate “Pizza” categories that are the same (except for the ID) but are used in different mealtimes.
- Do not create duplicate “Hawaiian Pizza” items (except for the ID) that are used in the two unique “Pizza” categories above.
- Do create separate categories when the items within them differ.
- Do create separate items when parts of the item differ.
Image caching
Mealtime and item images are downloaded and cached by Deliveroo using the image URL as the key.
When a menu is created or updated, for each image in the menu:
- If the image URL doesn't exist in the cache, the image is downloaded and cached and the new image is served.
- If the image URL exists in the cache, a HEAD request sent to the URL.
- If the
Etag
orLast-Modified
response headers indicate the image has changed, the image is downloaded and the cache is invalidated. - Otherwise the cached image is served.
- If the
Note: In order for partners to be able to change images when updating a menu without changing image URLs, the image servers need to respond to HEAD requests and return an Etag and/or Last-Modified header.
Fees
This includes all additional fees detailed by a partner that are included other than the price of items.
Deposit Return Scheme (DRS) Fees:
- The only accepted type is “DEPOSIT_FEE” for the IE (Ireland) market, if you send anything else (or send a deposit fee for another market) you will get a 400 validation error.
- The value cannot be duplicated, i.e. you cannot set 2 “DEPOSIT_FEE” elements in fees array.
- The amount should be multiples of 15 or 25 - however this rule only applies for top-level items (a top-level item is an item attached to a category); items that are offered only as part of modifier won’t have this validation applied.
External data
When creating or updating a menu, the external_data
field can be used to add extra information to a menu item. This could be an internal reference, or anything else that is useful to the restaurant.
When an order is placed, the Picking API webhook payload will include the external_data
field for each menu item in the order. The field will also be returned by the Get Menu endpoint.
Updated about 2 months ago