There are a number of menu element types (called “entities”), each with their own properties:

All
name string Required – The name to display
description string A short description
hidden boolean Used for temporarily removing an element from the menu
type string Identifies the type of the entity (SubMenu, Item, etc)
thirdPartyId string An identifier for your use, can be used for mapping between our systems
SubMenu
scheduleIds integer[] List of schedule ids that apply to the SubMenu
alcohol integer Indicates if it’s children should present an alcohol warning          (false => 0, true =>1)
tobacco integer Indicates if it’s children should present a tobacco warning           (false => 0, true =>1)
Item
scheduleIds integer[] List of schedule ids that apply to the Item
alcohol integer Indicates if the Item should present an alcohol warning                      (false => 0, true =>1)
tobacco integer Indicates if the Item should present a tobacco warning                        (false => 0, true =>1)
price float Required – The price of the item, if set to 0 a price group must be linked
qtyIncrements float Typically 1, determines the increments in which the quantity is selected: a value of 3 would mean the quantity options would be 3,5,9,etc
qtyMin float Typically 1
qtyMax float Typically 25, the maximum number of the item that can be order at once
qtyNameSingular string Displayed by the quantity when quantity is singular, ex: 1 lb.
qtyNameSingular string Displayed by the quantity when quantity is plural, ex: 5 lbs.
Option
price float The price of the option
qtyIncrements float Typically 1, determines the increments in which the quantity is selected: a value of 3 would mean the quantity options would be 3,5,9,etc
qtyMin float Typically 0, when greater than 0 the option is required
qtyMax float Varies based on OptionGroup selection type, for all but ‘quantity’ it will default to 1. For ‘quantity’, this determine the max amount of that option that can be selected.
qtyNameSingular string Displayed by the quantity when quantity is singular, ex: 1 lb.
qtyNameSingular string Displayed by the quantity when quantity is plural, ex: 5 lbs.
OptionGroup
selectionType radio|check|quantity|upToOne See below:
selectionType: radio The selection group will be a radio, the user must select exactly 1 option of quantity 1
selectionType: check The selection group will be a set of check boxes, the user selects between the min and max selections – each option of quantity 1
selectionType: quantity The selection group will be a set of dropdowns, the user selections a number of options up to the max selection – each option quantity can be up to the option’s max quantity – the total quantity of the options should be less than the max selections and greater than the min selections
selectionType: upToOne The selection group will be a set of check boxes, the user may select up to one option of quantity 1
selectionsMin integer The minimum number of selections required, this accounts for quantity as well
selectionsMax integer The maximum number of selections required, this accounts for quantity as well
selectionDepends boolean Can be used with type quantity. Typically used for catering, this changes how selections min and max relate with item quantity. E.g. If a user orders 3 orders of 12 sandwiches: When this is false, the user selects 12 sandwiches that selection will be tripled. When this is true, the user selects 36 sandwiches.
PriceGroup Effectively a radio option group
None N/A All values are pre-set for this entity type except for name and description
Image
url string The url the image file is located. This will be downloaded and hosted on our server

Each entity type, except Image, can have any number of children. There are rules for which entities each can have as children:

Entity Valid Children
SubMenu Either other SubMenus or Items, not both
Item Up to 1 PriceGroup, Up to 1 Image, Any number of OptionGroups
OptionGroup Any number of Options
PriceGroup Any number of Options
Option Up to 1 PriceGroup, Up to 1 Image, Any number of OptionGroups
Image None

Each entity type has a general purpose. A SubMenu is used for grouping Items or other SubMenus. Items are actual dishes or standalone beverages. OptionGroups are used to provide options such as toppings, sides, or drinks. PriceGroups vary conceptually from Optiongroups, the purpose is to allow a change in price of the parent.

PriceGroup example: A pizza has 3 available sizes: small, medium, and large. The choice in size influences the price of the parent.

You should only use PriceGroup over OptionGroup in this type of situation. In the data, your item price may either be 0 with the lowest PriceGroup option being the lowest price available, or you may price your item at the lowest price and have a price of 0 on your smallest option in the PriceGroup.

When building a menu, there are a number of calls to be made. First, if there are any schedules linked to an entity, that should be created first so that you may pass the scheduleId with the entity. You can find information on the menu schedule calls here. Second, submit all entities for the menu, multiple entities can be submitted in a single call. Last, submit the links between the entities. This can be done in stages or all at once. We also provide a call that allows you to submit a full menu structure.

The calls to create, update, and delete individual entities are as follows:

When creating an entity, you may include a parentId in the entity object as a shortcut to making a second call to create the link.

POST /merchant/admin/menu

{
    "merchantId"  : "1234",
    "entities"    : [
          {
                  "description": "Items of each type are represented here.",
                  "alcohol": 0,
                  "tobacco": 0,
                  "type": "SubMenu",
                  "scheduleIds": [1],
                  "name": "Lunch Menu"
           },
           {
                  "type": "Item",
                  "price": 6.99,
                  "alcohol": 0,
                  "tobacco": 0,
                  "name": "Lunch Box",
                  "description": "The item description"
           }
    ]
}

The entity ids will be returned in the order they were created. In case of failure, the message will include the full entity received with the relevant problem.

{<br />	"entityIds" : [1,2]<br />}

To make updates to entities, the id value is required along with the type.

PUT /merchant/admin/menu

{
	"merchantId"  : "1234",
	"entities"      : [
		{
		      "type": "SubMenu",
		      "id": 1,
		      "name": "Renamed Menu",
		},
		{
		      "type": "Item",
		      "id": 2,
		      "name": "Renamed Item",
		}
	]
}

Delete calls simply require the entity ids in a comma separated list:

DELETE /merchant/admin/menu?merchantId=1234&entityIds=1,2

Deletion of an entire menu should rarely be necessary, as changes should be handled via updates. If you require a removal of an entire menu, please contact your account manager to discuss the issue.

Once you have your entities created, you’ll need to link them together to form a menu tree. The link calls accept an array of link objects:

Property Name Type Notes
parentId integer|null Required – The id of the parent entity, or null if linking to the top level of the menu. This may only be null for subMenus, no other type may be linked to the top level.
childId integer Required – The id of the child entity
displayOrder integer Determines the display order under the parent. If left empty, the id is used to determine the order. Any entity with a display order of any value will come before entities with no value.

POST /merchant/admin/menu/link

{
	"merchantId"  : "1234",
	"links"      : [
		{
		      "parentId": null,
		      "childId": 1
		},
		{
		      "parentId": 1,
		      "childId": 2,
		      "displayOrder": 4
		}
	]
}

Ids are not given for links, to reference them for update and delete, you should use the parent and child id. You can not update the parent or child id. For links, the only value that can be edited is ‘displayOrder’.

PUT /merchant/admin/menu/link

{
	"merchantId"  : "1234",
	"links"      : [
		{
		      "parentId": null,
		      "childId": 1,
		      "displayOrder": 1
		},
		{
		      "parentId": 1,
		      "childId": 2,
		      "displayOrder": 2
		}
	]
}

DELETE /merchant/admin/menu/link

{
	"merchantId"  : "1234",
	"links"      : [
		{
		      "parentId": null,
		      "childId": 1
		},
		{
		      "parentId": 1,
		      "childId": 2
		}
	]
}

The fetch for the menu resource includes the schedule, menu structure, and an array of all entities. The array of all entities includes entities that have not been added to the menu structure.

GET /merchant/admin/menu?merchantId=1234

Response:

{
    "schedule": [
        {
            "id": 1,
            "name": "Lunch Specials",
            "hours": [
                {
                    "id": 1,
                    "day": 1,
                    "startTime": "11:30",
                    "endTime": "14:30"
                },
                {
                    "id": 2,
                    "day": 2,
                    "startTime": "11:30",
                    "endTime": "14:30"
                },
                {
                    "id": 3,
                    "day": 3,
                    "startTime": "11:30",
                    "endTime": "14:30"
                },
                {
                    "id": 4,
                    "day": 4,
                    "startTime": "11:30",
                    "endTime": "14:30"
                },
                {
                    "id": 5,
                    "day": 5,
                    "startTime": "11:30",
                    "endTime": "14:30"
                }
            ]
        }
    ],
    "menu": [
        {
            "description": "Items of each type are represented here.",
            "alcohol": false,
            "tobacco": false,
            "type": "SubMenu",
            "scheduleIds": [1],
            "name": "Test Menu",
            "children": [
                {
                    "type": "Item",
                    "price": 6.99,
                    "qtyIncrements": 1,
                    "qtyMin": 1,
                    "qtyMax": 25,
                    "qtyNameSingular": "",
                    "qtyNamePlural": "",
                    "alcohol": true,
                    "tobacco": false,
                    "name": "Simple Item",
                    "description": "",
                    "children": [
                    ]
                }
            ]
        }
    ],
    "entities": [
        {
            "description": "Items of each type are represented here.",
            "alcohol": false,
            "tobacco": false,
            "type": "SubMenu",
            "scheduleIds": [1],
            "name": "Test Menu",
            "children": [
                {
                    "type": "Item",
                    "price": 6.99,
                    "qtyIncrements": 1,
                    "qtyMin": 1,
                    "qtyMax": 25,
                    "qtyNameSingular": "",
                    "qtyNamePlural": "",
                    "alcohol": true,
                    "tobacco": false,
                    "name": "Simple Item",
                    "description": "",
                    "children": [
                    ]
                }
            ]
        },
        {
            "type": "Item",
            "price": 6.99,
            "qtyIncrements": 1,
            "qtyMin": 1,
            "qtyMax": 25,
            "qtyNameSingular": "",
            "qtyNamePlural": "",
            "alcohol": true,
            "tobacco": false,
            "name": "Simple Item",
            "description": "",
            "children": [
            ]
        }
    ],
    "warnings": [
        {
            "entityId": 8,
            "type": "tobacco"
        },
        {
            "entityId": 2,
            "type": "alcohol"
        }
    ],
    "message": []
}

To submit an entire menu structure, you must still have previously created the menu schedules if necessary. In cases of validation errors, the failed entities and it’s children will be excluded. A message will be returned indicating each failure.

POST /merchant/admin/menu/structure

{
  "merchantId": 1234,
  "menu": [
    {
      "description": "Items of each type are represented here.",
      "alcohol": false,
      "tobacco": false,
      "type": "SubMenu",
      "scheduleIds": [

      ],
      "name": "Test Menu",
      "children": [
        {
          "type": "Item",
          "price": 6.99,
          "qtyIncrements": 1,
          "qtyMin": 1,
          "qtyMax": 25,
          "qtyNameSingular": "",
          "qtyNamePlural": "",
          "alcohol": true,
          "tobacco": false,
          "name": "Simple Item",
          "description": "",
          "children": [
            {
              "type": "Image",
              "url": "https://static.delivery.com/merchant_logo.php?id=1234",
              "name": "Simple Item Image",
              "children": [

              ]
            }
          ]
        },
        {
          "type": "Item",
          "price": 0,
          "qtyIncrements": 1,
          "qtyMin": 1,
          "qtyMax": 25,
          "qtyNameSingular": "",
          "qtyNamePlural": "",
          "alcohol": false,
          "tobacco": false,
          "name": "Item, Price Group",
          "description": "",
          "hidden": false,
          "children": [
            {
              "type": "PriceGroup",
              "selectionsMin": 1,
              "selectionsMax": 1,
              "selectionType": "radio",
              "name": "Pick One",
              "description": "",
              "children": [
                {
                  "type": "Option",
                  "price": 1.99,
                  "qtyIncrements": 1,
                  "qtyMax": 1,
                  "name": "Small",
                  "description": ""
                },
                {
                  "type": "Option",
                  "price": 2.99,
                  "name": "Medium",
                  "description": ""
                },
                {
                  "type": "Option",
                  "price": 3.99,
                  "name": "Large",
                  "description": ""
                }
              ]
            }
          ]
        },
        {
          "type": "Item",
          "price": 6.99,
          "qtyIncrements": 1,
          "qtyMin": 1,
          "qtyMax": 25,
          "qtyNameSingular": "",
          "qtyNamePlural": "",
          "alcohol": true,
          "tobacco": true,
          "name": "Item, Option Group : Single",
          "description": "",
          "children": [
            {
              "type": "OptionGroup",
              "selectionsMin": 1,
              "selectionsMax": 1,
              "name": "Single Option Group",
              "description": "",
              "hidden": false,
              "children": [
                {
                  "type": "Option",
                  "price": 0,
                  "name": "Un",
                  "description": ""
                },
                {
                  "type": "Option",
                  "price": 0,
                  "name": "Dos",
                  "description": ""
                },
                {
                  "type": "Option",
                  "price": 0,
                  "name": "Tres",
                  "description": ""
                }
              ]
            }
          ]
        },
        {
          "type": "Item",
          "price": 6.99,
          "qtyIncrements": 1,
          "qtyMin": 1,
          "qtyMax": 25,
          "qtyNameSingular": "",
          "qtyNamePlural": "",
          "name": "Item, Option Group : Quantity",
          "description": "",
          "children": [
            {
              "type": "OptionGroup",
              "selectionsMin": 5,
              "selectionsMax": 5,
              "selectionsDepends": false,
              "selectionType": "quantity",
              "name": "Option Group Quantity (Select 5)",
              "description": "",
              "children": [
                {
                  "type": "Option",
                  "price": 0,
                  "name": "Option 1",
                  "description": "",
                  "children": [

                  ]
                },
                {
                  "type": "Option",
                  "price": 0,
                  "name": "Option 2",
                  "description": "",
                  "children": [

                  ]
                },
                {
                  "type": "Option",
                  "price": 0,
                  "name": "Option 3",
                  "description": "",
                  "children": [

                  ]
                }
              ]
            }
          ]
        },
        {
          "type": "Item",
          "scheduleIds": [
            1
          ],
          "price": 6.99,
          "qtyIncrements": 1,
          "qtyMin": 1,
          "qtyMax": 25,
          "qtyNameSingular": "",
          "qtyNamePlural": "",
          "name": "Item, Option Group : Upto One",
          "description": "",
          "children": [
            {
              "type": "OptionGroup",
              "selectionType": "upToOne",
              "name": "Optional Condiments",
              "description": "",
              "children": [
                {
                  "type": "Option",
                  "price": 1.99,
                  "qtyIncrements": 1,
                  "qtyMax": 1,
                  "name": "Egg Roll",
                  "description": ""
                },
                {
                  "type": "Option",
                  "price": 2.99,
                  "name": "Tuna Roll",
                  "description": ""
                },
                {
                  "type": "Option",
                  "price": 3.99,
                  "name": "Jellyfish Roll",
                  "description": ""
                }
              ]
            }
          ]
        },
        {
          "type": "Item",
          "price": 6.99,
          "qtyIncrements": 1,
          "qtyMin": 1,
          "qtyMax": 25,
          "qtyNameSingular": "",
          "qtyNamePlural": "",
          "name": "Item, Nested Option Group",
          "description": "",
          "children": [
            {
              "type": "OptionGroup",
              "selectionType": "radio",
              "name": "Choice of Combo",
              "description": "",
              "children": [
                {
                  "type": "Option",
                  "price": 0,
                  "name": "Burger and Soda",
                  "description": "",
                  "children": [
                    {
                      "type": "OptionGroup",
                      "selectionType": "radio",
                      "name": "Choice of Soda",
                      "description": "",
                      "children": [
                        {
                          "type": "Option",
                          "price": 0,
                          "name": "Pepsi",
                          "description": ""
                        },
                        {
                          "type": "Option",
                          "price": 0,
                          "name": "Coke",
                          "description": ""
                        },
                        {
                          "type": "Option",
                          "price": 0,
                          "name": "Sprite",
                          "description": ""
                        },
                        {
                          "type": "Option",
                          "price": 0,
                          "name": "Fanta",
                          "description": ""
                        }
                      ]
                    }
                  ]
                },
                {
                  "type": "Option",
                  "price": 0,
                  "name": "Pizza and Soda",
                  "description": "",
                  "children": [
                    {
                      "type": "OptionGroup",
                      "selectionType": "radio",
                      "name": "Choice of Soda",
                      "description": "",
                      "children": [
                        {
                          "type": "Option",
                          "price": 0,
                          "name": "Pepsi",
                          "description": ""
                        },
                        {
                          "type": "Option",
                          "price": 0,
                          "name": "Coke",
                          "description": ""
                        },
                        {
                          "type": "Option",
                          "price": 0,
                          "qtyIncrements": 1,
                          "qtyMax": 1,
                          "name": "Sprite",
                          "description": ""
                        },
                        {
                          "type": "Option",
                          "price": 0,
                          "qtyIncrements": 1,
                          "qtyMax": 1,
                          "name": "Fanta",
                          "description": ""
                        }
                      ]
                    }
                  ]
                },
                {
                  "type": "Option",
                  "price": 0,
                  "qtyIncrements": 1,
                  "qtyMax": 1,
                  "name": "Chowmein and Soda",
                  "description": "",
                  "children": [
                    {
                      "type": "OptionGroup",
                      "selectionType": "radio",
                      "name": "Choice of Soda",
                      "description": "",
                      "children": [
                        {
                          "type": "Option",
                          "price": 0,
                          "qtyIncrements": 1,
                          "name": "Pepsi",
                          "description": ""
                        },
                        {
                          "type": "Option",
                          "price": 0,
                          "name": "Coke",
                          "description": ""
                        },
                        {
                          "type": "Option",
                          "price": 0,
                          "name": "Sprite",
                          "description": ""
                        },
                        {
                          "type": "Option",
                          "price": 0,
                          "name": "Fanta",
                          "description": ""
                        }
                      ]
                    }
                  ]
                }
              ]
            }
          ]
        }
      ]
    }
  ]
}