Menu .: Show

Provider Enablement / Endpoints

Show Menu

Our menu structure attempts to make it easy to represent almost any menu cleanly within the LevelUp format, with a limited amount of translation/manipulation. Ascribing to this format makes it seamless for LevelUp to feature your merchants ordering experience in the LevelUp, a merchant-specific app we power, or any of our partner apps such as Chase Pay.

LevelUp’s menu structure affords you a lot of flexibility in terms of how you choose to represent a menu, and what information you include such as images and nutritional info. If you have specific questions about how to best represent your menu, please email and we’ll provide advice.

Our core menu format is comprised of the following entities:

  • General Information: LevelUp requires some top-level information about menus such as whether or not special instructions are allowed on orders and a name for the menu.

  • Categories: A category is a collection of items. I.E. a category like “Smoothies” might contain the following items: “Banana Smoothie”, “Strawberry Coolatta” and “Raspberry Fusion”. All menus have categories. Categories never have a price. Categories may have an optional attribute of a category group.

  • Category Groups: A category group is a collection into which a category fits. I.E. the following categories “Soft Drinks”, “Smoothies” and “Fresh Juices” might all have a category group of “Beverages”. Not all menus have category groups. If a category does not belong to a category group, simply don’t include a category group attribute under the category. Category groups never have a price. If some categories are under a category group and others are not, only fill out the category group attribute for those that have it.

  • Items: An item is a specific thing on a menu, that is included in categories and can have zero, one or many option groups. In the category “Smoothies”, one of the items might be “Banana Smoothie” and it might have options that allow for the customization of certain aspects of that item like “Size”, “Mix-Ins” or “Quantity”. Items always have prices, though the base price of an item might be $0 if the cost is derived entirely from its options. Items either allow for special instructions or don’t. Special instructions can have an optional character limit – if none is available, set the attribute value to nil and LevelUp defaults to 120. You may include images for items, as well as nutrition information if available. You may include optional metadata along with each item that can be passed back to you during order validation and submission. Any metadata key that begins with “integration-” will be passed back in this way. All other keys will be ignored.

  • Option Groups: An option group is a collection of options. Option groups always have a parent entity, that is either an item, or an option in another option group. For example, “Size” would be an option group with a parent that is simply the item “Banana Smoothie” and it contains options underneath it such as “8 oz”, “12 oz” and “16 oz”. Let’s say that if the user selected 16 oz, they also got to pick their cup’s design. That would be yet another option group, this time with a parent being the 16 oz option. I.E. “Cup Design” would be an option group, with a parent entity of “16 oz” and with options of “Toy Story Themed”, “Superman Themed” or “Star Wars Themed”. Option groups never have a price themselves, only the options have a price. Each option group also has validations that need to be gathered from the menu, i.e. “Select only 1” or “Pick at least 3.” or “Pick As Many As You Want, First One Free”, or “Pick at most 3 unique options”. The format for these requirements is described in LevelUp’s JSON menu structure.

  • Nested Options: Please note that LevelUp will return options in a “flattened” fashion in our order validation and order submission requests. So if you believe that a given item will require that options be presented in a nested fashion, you will need to encode that nesting logic into your option ids, using some delimiter such as “:” or “-”. I.E. parentoptiongroup:option_id so that you can parse it back out as needed. You can also include optional metadata along with each item, which can contain the appropriate nesting which we will echo back to you.

  • Options: Options are the items contained within option groups. For example, the options in the option group “Size” would be “8 oz”, “12 oz” and “16 oz”. Options can be the parents of other option groups. Options always have a price, even if that price is $0. When a user is able to select multiple of an option, that option can have a maximum_quantity that indicates the maximum number of that option the user can select. For example, for Dunkin Donuts coffee, the user can elect to add sweetener as an option, and then input the quantity that they want. Additionally, options can also have a default_quantity. For example, when sweetener is added to a medium Dunkin Donuts it comes default with (3) sweetener. When a default_quantity is not given, it will be assumed to be (1). Options have may nutrition information associated with them.

Additional description of certain attributes:

  • Nutrition: This property is optional but should be included whenever possible.

  • Menu Name: You can title your menu name as “Merchant_Name [Provider_Name]”. I.E. “Joe’s Coffee Shop [Revel]”.

  • Timescopes: This is a list of Timescope objects that are applied to the parent menu object. Timescopes are optional, and should not be provided or Nil if the menu object is always available, or if a Timescope is not determinable. See the “Timescopes and Partially Available Items” sub-section below for a more in-depth description of a Timescope object.

  • Defaults: Defaults should be passed back along with any option_group to let us know which are the options defaulted to true (i.e. preselected) on a given item. LevelUp will display these within our mobile UI as pre-checked and, assuming the user does not uncheck them, echo them back as normally selected options in the validate/submit call.

  • Other Notes:

    • IDs should, whenever possible, be persistent across menu refreshes.
    • IDs generally only need to be unique enough for you to be able to find the item again, since LevelUp returns item and options with their parent ids (such as categories, category groups or option_groups for options) included in the post. However, we do flatten all options under the top-level item, so if IDs for options are shared within the same item, you will have to make them unique for us.
    • If a category involves catering option, please always leave it out, unless explicitly requested by the merchant to include it within LevelUp. We don’t by default include any catering options.
    • Please be sure to return the categories, items, option groups, options in the order they are listed on the underlying menu. The sequence of things on a menu is something a merchant tends to put a lot of thought into to design it to be best suited for consumer habits. We want to make sure to respect/replicate that.
    • If special instructions are false, character count should be set to nil.
    • If Option groups have two sets of validations, namely minimum_choices/maximum_choices and minimum_unique_options/maximum_unique_options. The former is validated against the total quantity across all options a user selects, with each option defaulting to a quantity of (1). The latter is validated against the unique set of options a user selects for that option group, disregarding option quantities. For example, if for the option group “Select your bagels” a user selects 3x Plain and 3x Blueberry, their choices would be (6) and unique_options (2).

Timescopes and Partially Available Items: A Timescope object is used to specify when a menu object is available on the menu and can be ordered. The following menu objects support Timescopes: Categories, category groups, items, options and option groups.

A single object is composed of 3 sets of fields:

  • time_of_day_[starts|ends]_at - String in ISO 8601 Format (h:mm or hh:mm only, do not provide timezone information we assume the implied timezone is specific to that location) representing the hour and minute of a day the item is available. All times should be in the same timezone as the restaurant location. Set to null if available all day.

  • day_of_week_[starts|ends]_at - String (values: “Monday” through “Sunday” only, without the quotes) representing the days of the week, that the item is available. Set to null if available all week. date[starts|ends]at - String in ISO 8601 Format (YYYY-MM-DD only) representing the calendar date range that the item is available, inclusive. Set to null if unknown/available all year.

Each set is optional. For example, you can specify time_of_day_starts_at and time_of_day_ends_at without specifying the other sets to indicate the item is available during a certain period of the day, every day of the week, all year.

In the menu JSON each menu object can have a list of Timescope objects associated with it (this list is named “timescopes”). The list format is used to allow multiple availability periods (e.g. Mon 9-11 AM, Wed 9-11AM and Fri 9-11AM) to be specified for a specific object.

Example Timescopes list specifying that a particular breakfast sandwich is only available from 9-1130am on Mon, Wed, Fri:

"timescopes": [
    "time_of_day_ends_at" : "11:30",
    "time_of_day_starts_at" : "9:00",
    "day_of_week_ends_at" : "Monday",
    "day_of_week_starts_at" : "Monday",
    "date_ends_at" : null,
    "date_starts_at" : null
    "time_of_day_ends_at" : "11:30",
    "time_of_day_starts_at" : "9:00",
    "day_of_week_ends_at" : "Wednesday",
    "day_of_week_starts_at" : "Wednesday",
    "date_ends_at" : null,
    "date_starts_at" : null
    "time_of_day_ends_at" : "11:30",
    "time_of_day_starts_at" : "9:00",
    "day_of_week_ends_at" : "Friday",
    "day_of_week_starts_at" : "Friday",
    "date_ends_at" : null,
    "date_starts_at" : null

Request Endpoint

GET /locations/:provider_location_id/menu

Example Response Body