Enhanced menu options
In order to support increasingly complex restaurant menus, the Grubhub restaurants API has two versions that can produce different versions of menu items:
GET /restaurants/{restaurant_id}- Returns menu items with basic options. This is the version that has existed for years and is the default. Consider this the v1 endpoint.GET /restaurants/v4/{restaurant_id}- Returns menu items with advanced choice options, which include variable quantities in choice categories and options, options selected by default, combo items, options with images, and options with their own option categories.
It's this second one, the v4 endpoint, that has our enhanced menu items. These allow restaurants to provide a lot of flexibility in the menu items that they provide.
NOTE: The other versions of this endpoint, v2 and v3, should not be used. v2 is intended for internal Grubhub testing; v3 shows a subset of the enhanced menu features.
Let's take an example. Suppose a restaurant wants to sell a dozen chicken wings with variable sauce options. The v1 menu would include a single item, one dozen chicken wings with a sauce modifier choice for all wings. Maybe they could also include a blue cheese/ranch/etc. option as a dipping sauce. They throw the celery in for free.
But for the v4 menu, the restaurant could allow the diner to mix and match sauces, say three wings regular buffalo style, three jerk seasoned, and the other six a mild honey mustard. Each of those sauce options could include a spiciness sub-option. Those jerk wings sound pretty tasty, but you want to tone down the spice for the kids. The buffalo wings, meanwhile, are only for the cast iron stomach types.
The optional dipping sauce could have sub-options as well. Instead of just one size, the restaurant can offer multiple sizes at multiple price points, with the sauce type as a sub-option. Maybe they have a dairy-free ranch, so they can offer a sub-sub-option there. And that celery becomes an option included by default, so anybody who feels guilty about throwing it out can deselect it from their order.
Identifying enhanced menu items
Not every menu item is going to be enhanced in the v4 endpoint's return payload. Those that do will have one or more tags in the menu_item_features array within each specific MenuItem object.
This array can contain one or more of the following string values:
CHOICE_CATEGORY_QUANTITIES- Options can be added to the item in variable quantities. In general, this indicates a menu item with more than one item, each of which can have differing options (as in the wings example above).CHOICE_OPTION_QUANTITIES- Options have sub-options that can be added in variable quantities. This will always be present withCHOICE_CATEGORY_QUANTITIES.CHOICE_OPTION_DEFAULTS- Some options will be included as part of the default menu item, but they may be removed by the diner.MENU_ITEM_COMBOS- The current item is a combination of other items, each of which can be customized. Imagine a 6-pack of tacos where each can have toppings added or removed individually. This feature usually includesCHOICE_CATEGORY_QUANTITIES,CHOICE_OPTION_QUANTITIES, andSUBCATEGORIES.CHOICE_OPTION_MEDIA- Individual options have images associated with them.SUBCATEGORIES- Choice options have their own choice categories with separate options.
In addition, we've added a field to the choice_category_list object - display_settings - that indicates what the user interface will need to render in order to allow diners to correctly select options. Note that these are optional settings and are configured by the restaurant:
-CHOOSE_ONE_REQUIRED - One and only one option must be selected. We use a radio button control for this. -CHOOSE_ONE_OPTIONAL - One and only one option can be selected, but the diner can choose to select nothing. We use a check box control for this. -CHOOSE_MANY_REQUIRED - Multiple options must be selected. We use a check box control for this. -CHOOSE_MANY_OPTIONAL - Multiple options can be selected, but the diner can choose to select less than the maximum amount. We use a check box control for this. Note that a choice category can have both optional and required choices, where a diner would need to select at least one but could choose up to five. -CHOOSE_QUANTITY - All modifiers have a quantity associated with them. This is for assortment items, like a dozen doughnuts, where a diner could have multiples of each individual doughnut type. -COMBO_ITEM - This option is part of a combo, and may have sub-options of its own. -COMBO_ITEM_CHOOSE_ONE - Same as above, except there are multiple choice options from which the diner can select only one. -MODIFIER_ACTION_CHOOSE_ONE - A choice that modifies how an item or other choice is prepared.
Because these settings are configured outside of Grubhub's control, we recommend that you apply some fallback logic to menu rendering in cases where there are no display_settings. Our client applications use the minimum and maximum values to determine if some of these situations may apply even if the setting is absent.
Example
As these can be complex to understand, here are some examples of enhanced menu items taken from Grubhub test restaurants. These include both the JSON object for the menu item and a screenshot of the site with the JSON data rendered for diners.
We're going to start with a very complicated item that has almost all of the menu_item_features tags except for CHOICE_OPTION_QUANTITIES. It's a taco combo meal that lets the diner mix and match a dozen soft or crunchy tacos, while configuring some of the modifiers for them.
Here's the full JSON object for the menu item.
{
"uuid": "SG7zQ81iEeih1qPfa3Wqgw",
"id": "29448674",
"menu_category_name": "Taco Test Combos",
"menu_category_id": "3300445",
"name": "Taco 12 Pack",
"description": "Your choice of 12 of the following tacos: Crunchy or Soft Tacos, Crunchy or Soft Taco Supremes®.",
"price": {
"amount": 1429,
"currency": "USD"
},
"delivery_price": {
"amount": 1429,
"currency": "USD"
},
"pickup_price": {
"amount": 1299,
"currency": "USD"
},
"tax": 10,
"tax_rate": {
"name": "RestaurantTax",
"rate": 10,
"included_in_item_price": false
},
"minimum_cart_total": {
"amount": 0,
"currency": "USD"
},
"sequence": 2,
"minimum_price_variation": {
"amount": 1429,
"currency": "USD"
},
"delivery_minimum_price_variation": {
"amount": 1429,
"currency": "USD"
},
"pickup_minimum_price_variation": {
"amount": 1299,
"currency": "USD"
},
"maximum_price_variation": {
"amount": 2221,
"currency": "USD"
},
"delivery_maximum_price_variation": {
"amount": 2221,
"currency": "USD"
},
"pickup_maximum_price_variation": {
"amount": 2019,
"currency": "USD"
},
"available": true,
"choice_category_list": [
{
"uuid": "SG5XAc1iEeih1qPfa3Wqgw",
"id": "13806249",
"name": "First 6 Tacos",
"min_choice_options": 1,
"included_choice_options": 0,
"max_choice_options": 2,
"choice_option_list": [
{
"uuid": "SG26wc1iEeih1qPfa3Wqgw",
"id": "70488257",
"description": "Crunchy Tacos",
"price": {
"amount": 0,
"currency": "USD"
},
"delivery_price": {
"amount": 0,
"currency": "USD"
},
"pickup_price": {
"amount": 0,
"currency": "USD"
},
"choice_category_list": [
{
"uuid": "SGuX481iEeih1qPfa3Wqgw",
"id": "13806252",
"name": "Crunchy Taco Filling",
"min_choice_options": 0,
"included_choice_options": 0,
"max_choice_options": 3,
"choice_option_list": [
{
"uuid": "SGtJw81iEeih1qPfa3Wqgw",
"id": "70488262",
"description": "Seasoned Beef",
"price": {
"amount": 0,
"currency": "USD"
},
"choice_category_list": [
{
"uuid": "SGXykc1iEeih1qPfa3Wqgw",
"id": "13806236",
"name": "Regular, Extra",
"min_choice_options": 1,
"included_choice_options": 0,
"max_choice_options": 1,
"choice_option_list": [
{
"uuid": "SGV9Yc1iEeih1qPfa3Wqgw",
"id": "70488205",
"description": "Regular",
"price": {
"amount": 0,
"currency": "USD"
},
"choice_category_list": [],
"price_changes": {},
"sequence": 1,
"defaulted": true,
"tags": [],
"available": true
},
{
"uuid": "SGV9Y81iEeih1qPfa3Wqgw",
"id": "70488206",
"description": "Extra",
"price": {
"amount": 60,
"currency": "USD"
},
"choice_category_list": [],
"price_changes": {},
"sequence": 2,
"defaulted": false,
"tags": [],
"available": true
}
],
"variation_target": false,
"sequence": 1,
"display_settings": {
"display_type": "MODIFIER_ACTION_CHOOSE_ONE"
}
}
],
"price_changes": {},
"sequence": 1,
"defaulted": true,
"tags": [],
"available": true
},
{
"uuid": "SGtw0c1iEeih1qPfa3Wqgw",
"id": "70488263",
"description": "Lettuce",
"price": {
"amount": 0,
"currency": "USD"
},
"choice_category_list": [
{
"uuid": "SGixsc1iEeih1qPfa3Wqgw",
"id": "13806244",
"name": "Easy, Regular, Extra",
"min_choice_options": 1,
"included_choice_options": 0,
"max_choice_options": 1,
"choice_option_list": [
{
"uuid": "SGhjkc1iEeih1qPfa3Wqgw",
"id": "70488240",
"description": "Easy",
"price": {
"amount": 0,
"currency": "USD"
},
"choice_category_list": [],
"price_changes": {},
"sequence": 1,
"defaulted": false,
"tags": [],
"available": true
},
{
"uuid": "SGiKoc1iEeih1qPfa3Wqgw",
"id": "70488241",
"description": "Regular",
"price": {
"amount": 0,
"currency": "USD"
},
"choice_category_list": [],
"price_changes": {},
"sequence": 2,
"defaulted": true,
"tags": [],
"available": true
},
{
"uuid": "SGiKo81iEeih1qPfa3Wqgw",
"id": "70488242",
"description": "Extra",
"price": {
"amount": 0,
"currency": "USD"
},
"choice_category_list": [],
"price_changes": {},
"sequence": 3,
"defaulted": false,
"tags": [],
"available": true
}
],
"variation_target": false,
"sequence": 1,
"display_settings": {
"display_type": "MODIFIER_ACTION_CHOOSE_ONE"
}
}
],
"price_changes": {},
"sequence": 2,
"defaulted": true,
"tags": [],
"available": true
},
{
"uuid": "SGtw081iEeih1qPfa3Wqgw",
"id": "70488264",
"description": "Cheese",
"price": {
"amount": 0,
"currency": "USD"
},
"choice_category_list": [
{
"uuid": "SGixsc1iEeih1qPfa3Wqgw",
"id": "13806244",
"name": "Easy, Regular, Extra",
"min_choice_options": 1,
"included_choice_options": 0,
"max_choice_options": 1,
"choice_option_list": [
{
"uuid": "SGhjkc1iEeih1qPfa3Wqgw",
"id": "70488240",
"description": "Easy",
"price": {
"amount": 0,
"currency": "USD"
},
"choice_category_list": [],
"price_changes": {},
"sequence": 1,
"defaulted": false,
"tags": [],
"available": true
},
{
"uuid": "SGiKoc1iEeih1qPfa3Wqgw",
"id": "70488241",
"description": "Regular",
"price": {
"amount": 0,
"currency": "USD"
},
"choice_category_list": [],
"price_changes": {},
"sequence": 2,
"defaulted": true,
"tags": [],
"available": true
},
{
"uuid": "SGiKo81iEeih1qPfa3Wqgw",
"id": "70488242",
"description": "Extra",
"price": {
"amount": 0,
"currency": "USD"
},
"choice_category_list": [],
"price_changes": {},
"sequence": 3,
"defaulted": false,
"tags": [],
"available": true
}
],
"variation_target": false,
"sequence": 1,
"display_settings": {
"display_type": "MODIFIER_ACTION_CHOOSE_ONE"
}
}
],
"price_changes": {},
"sequence": 3,
"defaulted": true,
"tags": [],
"available": true
}
],
"variation_target": false,
"sequence": 1,
"display_settings": {
"display_type": "CHOOSE_MANY_OPTIONAL"
}
}
],
"price_changes": {},
"sequence": 1,
"defaulted": false,
"quantity_settings": {
"default_units": 6,
"maximum_units": 6,
"unit_increment": 1
},
"tags": [
{
"name": "COMBO_ITEM",
"id": 20
}
],
"asset_media": {
"base_url": "https://res.cloudinary.com/grubhub-pp/image/upload/",
"public_id": "f0r0qnzz2hipdps5wxu9",
"format": "jpg",
"tag": "placeholder"
},
"available": true
},
{
"uuid": "SG3h0c1iEeih1qPfa3Wqgw",
"id": "70488258",
"description": "Soft Tacos",
"price": {
"amount": 0,
"currency": "USD"
},
"delivery_price": {
"amount": 0,
"currency": "USD"
},
"pickup_price": {
"amount": 0,
"currency": "USD"
},
"choice_category_list": [
{
"uuid": "SGuX481iEeih1qPfa3Wqgw",
"id": "13806252",
"name": "Crunchy Taco Filling",
"min_choice_options": 0,
"included_choice_options": 0,
"max_choice_options": 3,
"choice_option_list": [
{
"uuid": "SGtJw81iEeih1qPfa3Wqgw",
"id": "70488262",
"description": "Seasoned Beef",
"price": {
"amount": 0,
"currency": "USD"
},
"choice_category_list": [
{
"uuid": "SGXykc1iEeih1qPfa3Wqgw",
"id": "13806236",
"name": "Regular, Extra",
"min_choice_options": 1,
"included_choice_options": 0,
"max_choice_options": 1,
"choice_option_list": [
{
"uuid": "SGV9Yc1iEeih1qPfa3Wqgw",
"id": "70488205",
"description": "Regular",
"price": {
"amount": 0,
"currency": "USD"
},
"choice_category_list": [],
"price_changes": {},
"sequence": 1,
"defaulted": true,
"tags": [],
"available": true
},
{
"uuid": "SGV9Y81iEeih1qPfa3Wqgw",
"id": "70488206",
"description": "Extra",
"price": {
"amount": 60,
"currency": "USD"
},
"choice_category_list": [],
"price_changes": {},
"sequence": 2,
"defaulted": false,
"tags": [],
"available": true
}
],
"variation_target": false,
"sequence": 1,
"display_settings": {
"display_type": "MODIFIER_ACTION_CHOOSE_ONE"
}
}
],
"price_changes": {},
"sequence": 1,
"defaulted": true,
"tags": [],
"available": true
},
{
"uuid": "SGtw0c1iEeih1qPfa3Wqgw",
"id": "70488263",
"description": "Lettuce",
"price": {
"amount": 0,
"currency": "USD"
},
"choice_category_list": [
{
"uuid": "SGixsc1iEeih1qPfa3Wqgw",
"id": "13806244",
"name": "Easy, Regular, Extra",
"min_choice_options": 1,
"included_choice_options": 0,
"max_choice_options": 1,
"choice_option_list": [
{
"uuid": "SGhjkc1iEeih1qPfa3Wqgw",
"id": "70488240",
"description": "Easy",
"price": {
"amount": 0,
"currency": "USD"
},
"choice_category_list": [],
"price_changes": {},
"sequence": 1,
"defaulted": false,
"tags": [],
"available": true
},
{
"uuid": "SGiKoc1iEeih1qPfa3Wqgw",
"id": "70488241",
"description": "Regular",
"price": {
"amount": 0,
"currency": "USD"
},
"choice_category_list": [],
"price_changes": {},
"sequence": 2,
"defaulted": true,
"tags": [],
"available": true
},
{
"uuid": "SGiKo81iEeih1qPfa3Wqgw",
"id": "70488242",
"description": "Extra",
"price": {
"amount": 0,
"currency": "USD"
},
"choice_category_list": [],
"price_changes": {},
"sequence": 3,
"defaulted": false,
"tags": [],
"available": true
}
],
"variation_target": false,
"sequence": 1,
"display_settings": {
"display_type": "MODIFIER_ACTION_CHOOSE_ONE"
}
}
],
"price_changes": {},
"sequence": 2,
"defaulted": true,
"tags": [],
"available": true
},
{
"uuid": "SGtw081iEeih1qPfa3Wqgw",
"id": "70488264",
"description": "Cheese",
"price": {
"amount": 0,
"currency": "USD"
},
"choice_category_list": [
{
"uuid": "SGixsc1iEeih1qPfa3Wqgw",
"id": "13806244",
"name": "Easy, Regular, Extra",
"min_choice_options": 1,
"included_choice_options": 0,
"max_choice_options": 1,
"choice_option_list": [
{
"uuid": "SGhjkc1iEeih1qPfa3Wqgw",
"id": "70488240",
"description": "Easy",
"price": {
"amount": 0,
"currency": "USD"
},
"choice_category_list": [],
"price_changes": {},
"sequence": 1,
"defaulted": false,
"tags": [],
"available": true
},
{
"uuid": "SGiKoc1iEeih1qPfa3Wqgw",
"id": "70488241",
"description": "Regular",
"price": {
"amount": 0,
"currency": "USD"
},
"choice_category_list": [],
"price_changes": {},
"sequence": 2,
"defaulted": true,
"tags": [],
"available": true
},
{
"uuid": "SGiKo81iEeih1qPfa3Wqgw",
"id": "70488242",
"description": "Extra",
"price": {
"amount": 0,
"currency": "USD"
},
"choice_category_list": [],
"price_changes": {},
"sequence": 3,
"defaulted": false,
"tags": [],
"available": true
}
],
"variation_target": false,
"sequence": 1,
"display_settings": {
"display_type": "MODIFIER_ACTION_CHOOSE_ONE"
}
}
],
"price_changes": {},
"sequence": 3,
"defaulted": true,
"tags": [],
"available": true
}
],
"variation_target": false,
"sequence": 1,
"display_settings": {
"display_type": "CHOOSE_MANY_OPTIONAL"
}
}
],
"price_changes": {},
"sequence": 2,
"defaulted": false,
"quantity_settings": {
"default_units": 0,
"maximum_units": 6,
"unit_increment": 1
},
"tags": [
{
"name": "COMBO_ITEM",
"id": 20
}
],
"asset_media": {
"base_url": "https://res.cloudinary.com/grubhub-pp/image/upload/",
"public_id": "rksn75nxqor0wgorjvhk",
"format": "jpg",
"tag": "placeholder"
},
"available": true
}
],
"variation_target": false,
"get_minimum_choice_price": {
"amount": 0,
"currency": "USD"
},
"get_maximum_choice_price": {
"amount": 0,
"currency": "USD"
},
"get_minimum_delivery_choice_price": {
"amount": 0,
"currency": "USD"
},
"get_maximum_delivery_choice_price": {
"amount": 0,
"currency": "USD"
},
"get_minimum_pickup_choice_price": {
"amount": 0,
"currency": "USD"
},
"get_maximum_pickup_choice_price": {
"amount": 0,
"currency": "USD"
},
"sequence": 1,
"quantity_settings": {
"maximum_units": 6,
"minimum_units": 6
},
"display_settings": {
"display_type": "CHOOSE_MANY_REQUIRED"
}
},
{
"uuid": "SG7zQc1iEeih1qPfa3Wqgw",
"id": "13806250",
"name": "Second 6 Tacos",
"min_choice_options": 1,
"included_choice_options": 0,
"max_choice_options": 2,
"choice_option_list": [
{
"uuid": "SG6lIc1iEeih1qPfa3Wqgw",
"id": "70488259",
"description": "Crunchy Tacos",
"label": "Giving you all something to taco bout.",
"price": {
"amount": 0,
"currency": "USD"
},
"delivery_price": {
"amount": 0,
"currency": "USD"
},
"pickup_price": {
"amount": 0,
"currency": "USD"
},
"choice_category_list": [
{
"uuid": "SGuX481iEeih1qPfa3Wqgw",
"id": "13806252",
"name": "Crunchy Taco Filling",
"min_choice_options": 0,
"included_choice_options": 0,
"max_choice_options": 3,
"choice_option_list": [
{
"uuid": "SGtJw81iEeih1qPfa3Wqgw",
"id": "70488262",
"description": "Seasoned Beef",
"price": {
"amount": 0,
"currency": "USD"
},
"choice_category_list": [
{
"uuid": "SGXykc1iEeih1qPfa3Wqgw",
"id": "13806236",
"name": "Regular, Extra",
"min_choice_options": 1,
"included_choice_options": 0,
"max_choice_options": 1,
"choice_option_list": [
{
"uuid": "SGV9Yc1iEeih1qPfa3Wqgw",
"id": "70488205",
"description": "Regular",
"price": {
"amount": 0,
"currency": "USD"
},
"choice_category_list": [],
"price_changes": {},
"sequence": 1,
"defaulted": true,
"tags": [],
"available": true
},
{
"uuid": "SGV9Y81iEeih1qPfa3Wqgw",
"id": "70488206",
"description": "Extra",
"price": {
"amount": 60,
"currency": "USD"
},
"choice_category_list": [],
"price_changes": {},
"sequence": 2,
"defaulted": false,
"tags": [],
"available": true
}
],
"variation_target": false,
"sequence": 1,
"display_settings": {
"display_type": "MODIFIER_ACTION_CHOOSE_ONE"
}
}
],
"price_changes": {},
"sequence": 1,
"defaulted": true,
"tags": [],
"available": true
},
{
"uuid": "SGtw0c1iEeih1qPfa3Wqgw",
"id": "70488263",
"description": "Lettuce",
"price": {
"amount": 0,
"currency": "USD"
},
"choice_category_list": [
{
"uuid": "SGixsc1iEeih1qPfa3Wqgw",
"id": "13806244",
"name": "Easy, Regular, Extra",
"min_choice_options": 1,
"included_choice_options": 0,
"max_choice_options": 1,
"choice_option_list": [
{
"uuid": "SGhjkc1iEeih1qPfa3Wqgw",
"id": "70488240",
"description": "Easy",
"price": {
"amount": 0,
"currency": "USD"
},
"choice_category_list": [],
"price_changes": {},
"sequence": 1,
"defaulted": false,
"tags": [],
"available": true
},
{
"uuid": "SGiKoc1iEeih1qPfa3Wqgw",
"id": "70488241",
"description": "Regular",
"price": {
"amount": 0,
"currency": "USD"
},
"choice_category_list": [],
"price_changes": {},
"sequence": 2,
"defaulted": true,
"tags": [],
"available": true
},
{
"uuid": "SGiKo81iEeih1qPfa3Wqgw",
"id": "70488242",
"description": "Extra",
"price": {
"amount": 0,
"currency": "USD"
},
"choice_category_list": [],
"price_changes": {},
"sequence": 3,
"defaulted": false,
"tags": [],
"available": true
}
],
"variation_target": false,
"sequence": 1,
"display_settings": {
"display_type": "MODIFIER_ACTION_CHOOSE_ONE"
}
}
],
"price_changes": {},
"sequence": 2,
"defaulted": true,
"tags": [],
"available": true
},
{
"uuid": "SGtw081iEeih1qPfa3Wqgw",
"id": "70488264",
"description": "Cheese",
"price": {
"amount": 0,
"currency": "USD"
},
"choice_category_list": [
{
"uuid": "SGixsc1iEeih1qPfa3Wqgw",
"id": "13806244",
"name": "Easy, Regular, Extra",
"min_choice_options": 1,
"included_choice_options": 0,
"max_choice_options": 1,
"choice_option_list": [
{
"uuid": "SGhjkc1iEeih1qPfa3Wqgw",
"id": "70488240",
"description": "Easy",
"price": {
"amount": 0,
"currency": "USD"
},
"choice_category_list": [],
"price_changes": {},
"sequence": 1,
"defaulted": false,
"tags": [],
"available": true
},
{
"uuid": "SGiKoc1iEeih1qPfa3Wqgw",
"id": "70488241",
"description": "Regular",
"price": {
"amount": 0,
"currency": "USD"
},
"choice_category_list": [],
"price_changes": {},
"sequence": 2,
"defaulted": true,
"tags": [],
"available": true
},
{
"uuid": "SGiKo81iEeih1qPfa3Wqgw",
"id": "70488242",
"description": "Extra",
"price": {
"amount": 0,
"currency": "USD"
},
"choice_category_list": [],
"price_changes": {},
"sequence": 3,
"defaulted": false,
"tags": [],
"available": true
}
],
"variation_target": false,
"sequence": 1,
"display_settings": {
"display_type": "MODIFIER_ACTION_CHOOSE_ONE"
}
}
],
"price_changes": {},
"sequence": 3,
"defaulted": true,
"tags": [],
"available": true
}
],
"variation_target": false,
"sequence": 1,
"display_settings": {
"display_type": "CHOOSE_MANY_OPTIONAL"
}
}
],
"price_changes": {},
"sequence": 1,
"defaulted": false,
"quantity_settings": {
"default_units": 6,
"maximum_units": 6,
"unit_increment": 1
},
"tags": [
{
"name": "COMBO_ITEM",
"id": 20
}
],
"asset_media": {
"base_url": "https://res.cloudinary.com/grubhub-pp/image/upload/",
"public_id": "f0r0qnzz2hipdps5wxu9",
"format": "jpg",
"tag": "placeholder"
},
"available": true
},
{
"uuid": "SG7MMc1iEeih1qPfa3Wqgw",
"id": "70488260",
"description": "Soft Tacos",
"label": "Taco bout it quietly",
"price": {
"amount": 0,
"currency": "USD"
},
"delivery_price": {
"amount": 0,
"currency": "USD"
},
"pickup_price": {
"amount": 0,
"currency": "USD"
},
"choice_category_list": [
{
"uuid": "SGuX481iEeih1qPfa3Wqgw",
"id": "13806252",
"name": "Crunchy Taco Filling",
"min_choice_options": 0,
"included_choice_options": 0,
"max_choice_options": 3,
"choice_option_list": [
{
"uuid": "SGtJw81iEeih1qPfa3Wqgw",
"id": "70488262",
"description": "Seasoned Beef",
"price": {
"amount": 0,
"currency": "USD"
},
"choice_category_list": [
{
"uuid": "SGXykc1iEeih1qPfa3Wqgw",
"id": "13806236",
"name": "Regular, Extra",
"min_choice_options": 1,
"included_choice_options": 0,
"max_choice_options": 1,
"choice_option_list": [
{
"uuid": "SGV9Yc1iEeih1qPfa3Wqgw",
"id": "70488205",
"description": "Regular",
"price": {
"amount": 0,
"currency": "USD"
},
"choice_category_list": [],
"price_changes": {},
"sequence": 1,
"defaulted": true,
"tags": [],
"available": true
},
{
"uuid": "SGV9Y81iEeih1qPfa3Wqgw",
"id": "70488206",
"description": "Extra",
"price": {
"amount": 60,
"currency": "USD"
},
"choice_category_list": [],
"price_changes": {},
"sequence": 2,
"defaulted": false,
"tags": [],
"available": true
}
],
"variation_target": false,
"sequence": 1,
"display_settings": {
"display_type": "MODIFIER_ACTION_CHOOSE_ONE"
}
}
],
"price_changes": {},
"sequence": 1,
"defaulted": true,
"tags": [],
"available": true
},
{
"uuid": "SGtw0c1iEeih1qPfa3Wqgw",
"id": "70488263",
"description": "Lettuce",
"price": {
"amount": 0,
"currency": "USD"
},
"choice_category_list": [
{
"uuid": "SGixsc1iEeih1qPfa3Wqgw",
"id": "13806244",
"name": "Easy, Regular, Extra",
"min_choice_options": 1,
"included_choice_options": 0,
"max_choice_options": 1,
"choice_option_list": [
{
"uuid": "SGhjkc1iEeih1qPfa3Wqgw",
"id": "70488240",
"description": "Easy",
"price": {
"amount": 0,
"currency": "USD"
},
"choice_category_list": [],
"price_changes": {},
"sequence": 1,
"defaulted": false,
"tags": [],
"available": true
},
{
"uuid": "SGiKoc1iEeih1qPfa3Wqgw",
"id": "70488241",
"description": "Regular",
"price": {
"amount": 0,
"currency": "USD"
},
"choice_category_list": [],
"price_changes": {},
"sequence": 2,
"defaulted": true,
"tags": [],
"available": true
},
{
"uuid": "SGiKo81iEeih1qPfa3Wqgw",
"id": "70488242",
"description": "Extra",
"price": {
"amount": 0,
"currency": "USD"
},
"choice_category_list": [],
"price_changes": {},
"sequence": 3,
"defaulted": false,
"tags": [],
"available": true
}
],
"variation_target": false,
"sequence": 1,
"display_settings": {
"display_type": "MODIFIER_ACTION_CHOOSE_ONE"
}
}
],
"price_changes": {},
"sequence": 2,
"defaulted": true,
"tags": [],
"available": true
},
{
"uuid": "SGtw081iEeih1qPfa3Wqgw",
"id": "70488264",
"description": "Cheese",
"price": {
"amount": 0,
"currency": "USD"
},
"choice_category_list": [
{
"uuid": "SGixsc1iEeih1qPfa3Wqgw",
"id": "13806244",
"name": "Easy, Regular, Extra",
"min_choice_options": 1,
"included_choice_options": 0,
"max_choice_options": 1,
"choice_option_list": [
{
"uuid": "SGhjkc1iEeih1qPfa3Wqgw",
"id": "70488240",
"description": "Easy",
"price": {
"amount": 0,
"currency": "USD"
},
"choice_category_list": [],
"price_changes": {},
"sequence": 1,
"defaulted": false,
"tags": [],
"available": true
},
{
"uuid": "SGiKoc1iEeih1qPfa3Wqgw",
"id": "70488241",
"description": "Regular",
"price": {
"amount": 0,
"currency": "USD"
},
"choice_category_list": [],
"price_changes": {},
"sequence": 2,
"defaulted": true,
"tags": [],
"available": true
},
{
"uuid": "SGiKo81iEeih1qPfa3Wqgw",
"id": "70488242",
"description": "Extra",
"price": {
"amount": 0,
"currency": "USD"
},
"choice_category_list": [],
"price_changes": {},
"sequence": 3,
"defaulted": false,
"tags": [],
"available": true
}
],
"variation_target": false,
"sequence": 1,
"display_settings": {
"display_type": "MODIFIER_ACTION_CHOOSE_ONE"
}
}
],
"price_changes": {},
"sequence": 3,
"defaulted": true,
"tags": [],
"available": true
}
],
"variation_target": false,
"sequence": 1,
"display_settings": {
"display_type": "CHOOSE_MANY_OPTIONAL"
}
}
],
"price_changes": {},
"sequence": 2,
"defaulted": false,
"quantity_settings": {
"default_units": 0,
"maximum_units": 6,
"unit_increment": 1
},
"tags": [
{
"name": "COMBO_ITEM",
"id": 20
}
],
"asset_media": {
"base_url": "https://res.cloudinary.com/grubhub-pp/image/upload/",
"public_id": "rksn75nxqor0wgorjvhk",
"format": "jpg",
"tag": "placeholder"
},
"available": true
}
],
"variation_target": false,
"get_minimum_choice_price": {
"amount": 0,
"currency": "USD"
},
"get_maximum_choice_price": {
"amount": 0,
"currency": "USD"
},
"get_minimum_delivery_choice_price": {
"amount": 0,
"currency": "USD"
},
"get_maximum_delivery_choice_price": {
"amount": 0,
"currency": "USD"
},
"get_minimum_pickup_choice_price": {
"amount": 0,
"currency": "USD"
},
"get_maximum_pickup_choice_price": {
"amount": 0,
"currency": "USD"
},
"sequence": 2,
"quantity_settings": {
"maximum_units": 6,
"minimum_units": 6
},
"display_settings": {
"display_type": "CHOOSE_MANY_REQUIRED"
}
}
],
"tag_list": [],
"media_image": {
"base_url": "https://res.cloudinary.com/grubhub-pp/image/upload/",
"public_id": "fwjintse12x6xocv0d4y",
"format": "jpg",
"tag": "placeholder"
},
"menu_item_features": [
"CHOICE_CATEGORY_QUANTITIES",
"CHOICE_OPTION_MEDIA",
"MENU_ITEM_COMBOS",
"CHOICE_OPTION_DEFAULTS",
"SUBCATEGORIES"
]
},
This item has two top level choice categories — "First 6 Tacos" and "Second 6 Tacos". Both of them have the same choice structure, which includes two levels of choice categories and options. We already knew to expect this, as this item has the SUBCATEGORIES feature. It also has the MENU_ITEM_COMBOS feature, which usually indicates that there will be more complex options for this item on its subcategories.
Here's what this choice structure looks like with all of the choice selectors rolled-up:
EM-choice-roll-up.png
Notice that the second choice category displays below the first. We use that convention for all subcategories except that last one. For the last one, we have selectable option names:
EM-last-subcategory.png
Let's take a look at the first level of our choices.
EM-taco-select.png
This selector presents two choices, each of which has a quantity selector control and a checkbox selector for the overall choice. The display_settings field tells us that this is CHOOSE_MANY_REQUIRED, which means that you can select more than one option, but must have at least one selected. For this, we use the non-exclusive checkbox control. In the choice JSON, here's how the checkbox selector is defined:
"min_choice_options": 1,
"included_choice_options": 0,
"max_choice_options": 2,
As for the quantity controls, those are indicated by the following fields in the choice category:
"quantity_settings": {
"maximum_units": 6,
"minimum_units": 6
}
and in each choice option object:
"quantity_settings": {
"default_units": 6,
"maximum_units": 6,
"unit_increment": 1
},
We know that the combined value of the individual option quantities must not exceed the category quantity as the menu item has the feature CHOICE_CATEGORY_QUANTITIES. If it had CHOICE_OPTION_QUANTITIES instead, then the options could have quantities that weren't limited by the category's values.
These options also have a special field to indicate that this is a combo item choice, and the quantity for both choices should exceed the maximum in the category:
"tags": [
{
"name": "COMBO_ITEM",
"id": 20
}
],
Each of these choices has its own choice_category_list. Let's move one level deeper to see how these work.
EM-last-subcategory.png
Here we see both the second and third levels of options. The category, "Crunchy Taco Filling", has three options: "Seasoned Beef", "Lettuce", and "Cheese". All of these have non-exclusive checkboxes, so you can select any and all of them. In this category's features, we see CHOOSE_MANY_OPTIONAL. It's similar to the previous level, except that you could conceivably unselect all options and get six taco shells with sour cream in them. Here's what the category and options look like:
"choice_category_list": [
{
"uuid": "SGuX481iEeih1qPfa3Wqgw",
"id": "13806252",
"name": "Crunchy Taco Filling",
"min_choice_options": 0,
"included_choice_options": 0,
"max_choice_options": 3,
"choice_option_list": [
{
"uuid": "SGtJw81iEeih1qPfa3Wqgw",
"id": "70488262",
"description": "Seasoned Beef",
"price": {
"amount": 0,
"currency": "USD"
},
"choice_category_list": [
...
],
"price_changes": {},
"sequence": 1,
"defaulted": true,
"tags": [],
"available": true
},
{
"uuid": "SGtw0c1iEeih1qPfa3Wqgw",
"id": "70488263",
"description": "Lettuce",
"price": {
"amount": 0,
"currency": "USD"
},
"choice_category_list": [
...
],
"price_changes": {},
"sequence": 2,
"defaulted": true,
"tags": [],
"available": true
},
{
"uuid": "SGtw081iEeih1qPfa3Wqgw",
"id": "70488264",
"description": "Cheese",
"price": {
"amount": 0,
"currency": "USD"
},
"choice_category_list": [
...
],
"price_changes": {},
"sequence": 3,
"defaulted": true,
"tags": [],
"available": true
}
],
"variation_target": false,
"sequence": 1,
"display_settings": {
"display_type": "CHOOSE_MANY_OPTIONAL"
}
}
],
This is pretty straightforward. The fields to look for are "min_choice_options": 0, "included_choice_options": 0, and "max_choice_options": 3. In each option, note the field "defaulted": true. All this means is that the filling options are all selected by default, but the diner could unselect any or all of them, but they will receive no discounts for doing so (that is, the options are not "included").
In the third level, the diner can configure how much of each selected filling they want. Some of these selections have additional costs. To indicate that these options should be rendered as a required modifier for the previous choice, this category includes the feature, MODIFIER_ACTION_CHOOSE_ONE. This also means the diner can select one and only one modifier.
Here's the JSON data for the beef option:
"uuid": "SGtJw81iEeih1qPfa3Wqgw",
"id": "70488262",
"description": "Seasoned Beef",
"price": {
"amount": 0,
"currency": "USD"
},
"choice_category_list": [
{
"uuid": "SGXykc1iEeih1qPfa3Wqgw",
"id": "13806236",
"name": "Regular, Extra",
"min_choice_options": 1,
"included_choice_options": 0,
"max_choice_options": 1,
"choice_option_list": [
{
"uuid": "SGV9Yc1iEeih1qPfa3Wqgw",
"id": "70488205",
"description": "Regular",
"price": {
"amount": 0,
"currency": "USD"
},
"choice_category_list": [],
"price_changes": {},
"sequence": 1,
"defaulted": true,
"tags": [],
"available": true
},
{
"uuid": "SGV9Y81iEeih1qPfa3Wqgw",
"id": "70488206",
"description": "Extra",
"price": {
"amount": 60,
"currency": "USD"
},
"choice_category_list": [],
"price_changes": {},
"sequence": 2,
"defaulted": false,
"tags": [],
"available": true
}
],
"variation_target": false,
"sequence": 1,
"display_settings": {
"display_type": "MODIFIER_ACTION_CHOOSE_ONE"
}
}
],
"price_changes": {},
"sequence": 1,
"defaulted": true,
"tags": [],
"available": true
Notice how the fields are setup for it: "min_choice_options": 1 and "max_choice_options": 1 one and only one selection. For the "Extra" option, notice that the price object has a non-zero amount. If the diner selects this option, their total increases by that amount (plus taxes).
This example covers most of the scenarios that you'll encounter.