Skip to main content

Menu Engine API | Getting Started

The process to get started with Menu Engine API is outlined in the table. Note that each step is its own process.

Step

Topic

Description

1

Getting Started with APIs

Steps to obtain an integrator token and additional information about our APIs.

2

Confidentiality Statement

Information about our non-disclosure agreement (NDA) terms and conditions regarding endpoints.

3

API Prerequisites

A list of prerequisites to complete before starting the integration development process.

Menu Engine API | Next Steps

After setting up the Menu Engine in the Portal, see the following topics for additional information.

Step

Topic

Description

1

URLs

Information for the different Menu Engine API environments for testing and Production.

2

Webhooks

Information on the use of webhooks.

3

Quick Start

The steps to calculate and retrieve a menu.

4

Operation Definitions

The operation definitions including the endpoints, data models, and sample code.

5

Pricing Menu

The steps to generate a menu that that includes only a list of menu items and their pricing data.

6

Menu Structure

The steps to organize menus by menu categories and menu item groups.

7

Item Availability

The steps to allow for variable availability for individual menu items.

URLs

Menu Engine API includes testing and production environments. When an application is in development, replace {{ me_url}} with the testing URL defined below. Update the base path to the production URL when the application passes testing:

Environment

URL

Testing (UAT)

https://uat-xme.xenial.com/v1

Production

https://xme.xenial.com/v1

Webhooks

Using webhooks eliminates polling the Menu Status endpoint. The Quick Start guide below describes how to set your webhook callback URL using the "url" field in the PUT request to the /menu/?timestamp endpoint.

Quick Start

Follow the procedure below to calculate and retrieve a menu based on a site ID and timestamp.

Define all required products and menus with Data Management before using the Menu Engine API. See the Menu Structure and connected topics for additional information on creating a menu with Data Management.

Integrators can also request a special type of menu called a pricing menu. A pricing menu is essentially a catalog of menu items and their associated prices, with the hierarchical structure of the standard menu excluded. See the Pricing Menu topic for additional information.

Step

Description and Example

1

Send a PUT request to /menu/?timestamp.

Request that our system create a menu by updating product lists and calculating prices based on a site ID and a timestamp. The site ID included in the header identifies which location the menu is for. The url field sets the webhook callback URL. The example below shows the URL and request.

Including a callback URL in the url field of the request body prompts Menu Engine to send the menu status object to the specified URL using the X-CB-Authorization header value. If the user does not specify a callback URL, they will not be notified upon the completion of the menu.

To create a pricing menu instead of a standard menu, include "menu_type": "price" in the request body. To create separate menus for specific time periods, include "create_time_period_menus": true in the request body.

PUT:

{{me_url}}/menu?effective_date=20YY-00-00T00:00:00.000Z

HEADER:

Authorization: Bearer <auth token>
Content-Type: application/json
X-Company-Id: 9999999999999999
X-Site-Ids: 9999999999999999
X-CB-Authorization: <client-token>

BODY:

{
   "order_source_ids": [
     "10"
   ],
   "url": "{{callback_url}}",
   "include_inactive": true,
   "enforce_same_size_children_variations": true,
   "time_period_entity_ids": [
     "{{time_period_entity_id}}"
   ]
}

For more information, see CreateMenuRequestBody.

2

Capture the menu ID ("mcid") that is returned in the CreateMenuResponseBody. The menu ID is required to retrieve the menu status and menu definition in the next steps.

Our system returns a menu ID and a status message. The example below shows the response.

{
    "mcid": "9999999999999999",
    "status": "pending",
    "version": "1.0.0",
    "store_number": "99999",
    "timestamp": "20YY-03-07T20:42:17.986Z"
}

For more information, see CreateMenuResponseBody.

You will receive a notification at the webhook URL when the status value changes. Look for "status": "available".

{
    "mcid": "9999999999999999",
    "status": "available",
    "version": "1.0.0",
    "store_number": "99999",
    "timestamp": "20YY-03-07T20:42:17.986Z"
}

3

Send a GET request to the /menu/{{mcid}} endpoint, to request the complete menu.

The example below shows the URL and header for the request.

GET:

/menu/9999999999999999

HEADER:

Authorization: Bearer <auth token>
Content-Type: application/json
X-Company-Id: 9999999999999999
X-Site-Ids: 9999999999999999

4

Our system returns a complete menu in the MenuObjectSuccessResponseBody as a JSON object as shown in the sample response below.

Sample /menu/{mcid} response

{
    "company_id": "company_id",
    "site_id": "site_id",
    "version": "1.0.0",
    "server_timestamp": "0000-00-00T00:00:00.000Z",
    "menu_timestamp": "0000-00-00T00:00:00.000Z",
    "menu_type": "Site",
    "mcid": "mcid",
    "menus": [{
            "name": "Main Menu Name", 
			// required
            "entity_id": "menu_entity_id", 
			// required
            "categories": [{
                    "name": "Menu Category Name", 
		// required
                    "entity_id": "category_entity_id", 
		// required
                    "groups": [{
                            "name": "Menu Group Name", 
			// required
                            "entity_id": "group_entity_id", 
			// required
                            "items": [{
                                    "description": 
				..."Product Description",
                                    "name": "Product name", 
				// required
                                    "product_id": "id", 
				// required
                                    "unit_price": 1, 
				// required
                                    "modifier_collection_entity_id":
                                 ..."modifier_collection_entity_id",
                                    "default_modifiers_entity_ids": [
                                        "modifier_entity_id"
                                    ],
                                    "is_bundle": true,
                                    "images": [{
                                            "image_set_entity_id": 
					..."image entity id",
                                            "tag": "Tag of image",
                                            "source_url": 
					..."url of image"
                                        }
                                    ],
                                    "variant_name": "Name of variant", 
// Typically Large/Medium/Small, 
   but can be whatever the integrator decides
                                    "variant_type": "size or meal", 
// Used for determining the type of variant 
   for resizing or meal conversion
                                    "bundle_components": [{
                                            "name": "Sides",
                                            "minimum_quantity": 2,
                                            "maximum_quantity": 2,
                                            "entity_id": 
					..."bundle_component_entity_id",
                                            "items": [{
                                                    "name": "Product name",
                                                    "product_id": "id",
                                                    "unit_price": 0,
                                                    ...
                                                }
                                            ]
                                        }
                                    ]
                                }
                            ]
                        }
                    ]
                }
            ],
            "modifier_collections": [{
                    "name": "Modifier Collection Name", 
                    // required
                    "entity_id": "modifier_collection_entity_id", 
                    // required
                    "minimum_quantity": 0, 
        // Exists ONLY if there are modifierss without groups
                    "maximum_quantity": 0, 
        // Exists ONLY if there are modifierss without groups
                    "modifiers": [{
                            "type": "parent_modifier", 
        // "parent_modifier" means the product is not orderable 
           and will havenested "variations" of the modifier that
           are to be ordered instead. The "parent_modifier" will
           have an entity_id instead of a product_id
                            "entity_id": "modifier_entity_id", 
// Exists only if modifier is a parent_modifier type
                            "product_id": "id", 
// Exists only if modifier is NOT a parent_modifier type
                            "default_unit_price": 0, 
// Exists only if modifier is NOT a parent_modifier type
                            "prices": [{ 
// Only exists if there are different prices based on parent products,
       AND if modifier is NOT a parent_modifier type
                                    "parent_product_entity_ids": 
                                    ...["product_id"],
                                    "unit_price": 1
                                }
                            ],
                            "description": "Modifier description",
                            "variations": [{
                                "product_id": "id", // required
                                "name": "Name", // required
                                "default_unit_price": 0, // required
                                "variation_name": 
				..."Lite, Add, No, Extra, etc.",
                                "prices": [{ 
// Only exists if there are different prices based on parent products
                                        "parent_product_entity_ids": 
					...["product_id"],
                                        "unit_price": 1
                                    }
                                ]
                            }]
                        }
                    ],
                    "groups": [{
                            "name": "Modifier Group Name", 
                                // required
                            "entity_id": "modifier_group_entity_id", 
                                // required
                            "minimum_quantity": 0, // required
                            "maximum_quantity": 0, // required
                            "modifiers": [{
                                    "type": "parent_modifier", 
// "parent_modifier" means the product is not
                           orderable and will have nested "variations" 
                           of the modifier that are to be ordered instead.
                           The "parent_modifier" will have an entity_id 
                           instead of a product_id
                                    "entity_id": "modifier_entity_id", 
// Exists only if modifier is a parent_modifier type
                                    "product_id": "id",
// Exists only if modifier is NOT a parent_modifier type
                                    "description": "Modifier description",
                                    "variations": [{
                                        "product_id": "id", // required
                                        "name": "Name", // required
                                        "default_unit_price": 0, // required
                                        "variation_name": "Lite, ...
					...Add, No, Extra, etc.",
                                        "prices": [{ 
// Only exists if there are different prices based on parent products
                                                "parent_product_entity_ids": 
						...["product_id"],
                                                "unit_price": 1
                                            }
                                        ]
                                    }]
                                }
                            ]
                        }
                    ]
                }
            ]
        }
    ]
}

For more information, see MenuObjectSuccessResponseBody.