---
title: "Upload Menu"
method: PUT
path: "/menus"
tags: ["Menu API Grubtech Endpoints"]
---

# Upload Menu

`PUT /menus`

## Request

- Base URL: `https://api.staging.grubtech.io/menu/v1`
- URL: `https://api.staging.grubtech.io/menu/v1/menus`
- Auth: API key in header `X-API-KEY`

The Upload Menu endpoint on the Grubtech platform allows the creation of a menu for a specific store. This endpoint is designed to handle complex menu structures and ensures that all menu items, categories, and modifiers are uploaded and properly configured for integration with Grubtech's POS application. 

 - **Menu Creation:** This endpoint facilitates the creation and structuring of a restaurant's menu on Grubtech's platform.

- **Store-Specific Menus:** The menu being uploaded is associated with a specific store, ensuring that each store can have a distinct menu if needed.

- **Supports Nested Modifiers:** For POS systems that support nested modifiers (i.e., modifiers within modifiers), this endpoint allows for the inclusion of those nested structures within the menu payload. Nested modifiers allow for hierarchical grouping, where a modifier can have additional sub-options. To properly configure nested modifiers, refer to the step-by-step process outlined in [POS Platforms Supporting Nested Modifiers](https://docs.grubtech.io/docs/menu-integration-1). Ensure that the payload follows the correct format to nest these modifiers.

## Request body

- Menu
  - `id` string, required: Unique identifier for the menu, provided by the integration party.
  - `name` MultiLingualText, required: Content for a string displayed to users in multiple languages <br/> Supported laguages (Locale ids) <br/> * en-us :- English (United States) <br/> * ar-ae :- Arabic (United Arab Emirates)
    - `translations` Translations, required: A mapping from locale code to the translated text in each locale. One translation must be provided. Currently, we do not support additional translations. When displaying text, we will first attempt to use the translation for the locale used by the user’s device, then, if not found, the restaurant’s locale, and finally the default locale for the city. If none of these are found, the first locale listed will be used. Locale codes should specify both language and country codes, e.g. "en-us", "ar-ae"
  - `description` MultiLingualText: Content for a string displayed to users in multiple languages <br/> Supported laguages (Locale ids) <br/> * en-us :- English (United States) <br/> * ar-ae :- Arabic (United Arab Emirates)
    - `translations` Translations, required: A mapping from locale code to the translated text in each locale. One translation must be provided. Currently, we do not support additional translations. When displaying text, we will first attempt to use the translation for the locale used by the user’s device, then, if not found, the restaurant’s locale, and finally the default locale for the city. If none of these are found, the first locale listed will be used. Locale codes should specify both language and country codes, e.g. "en-us", "ar-ae"
  - `imageUrl` string, required: URL pointing to an image of the item. <br/> Image requirements <br/> - File size must be less than 2MB. <br/> - Image must be in JPEG, PNG. <br/> - Optimal resolution for the images will be 800 x 800 px.
  - `currencyCode` string, required: Applicable currency code for the menu.
  - `storeIds` string[], required: Unique identifiers (string) for each locations which shared the menu
  - `externalData` string: (optional) Free-form text field reserved for the api consumer to use, e.g. for POS integrations.
  - `items` Item[], required: List of items in the menu.
    - `id` string, required: Unique id for the item.
    - `name` MultiLingualText, required: Content for a string displayed to users in multiple languages <br/> Supported laguages (Locale ids) <br/> * en-us :- English (United States) <br/> * ar-ae :- Arabic (United Arab Emirates)
      - `translations` Translations, required: A mapping from locale code to the translated text in each locale. One translation must be provided. Currently, we do not support additional translations. When displaying text, we will first attempt to use the translation for the locale used by the user’s device, then, if not found, the restaurant’s locale, and finally the default locale for the city. If none of these are found, the first locale listed will be used. Locale codes should specify both language and country codes, e.g. "en-us", "ar-ae"
    - `description` MultiLingualText: Content for a string displayed to users in multiple languages <br/> Supported laguages (Locale ids) <br/> * en-us :- English (United States) <br/> * ar-ae :- Arabic (United Arab Emirates)
      - `translations` Translations, required: A mapping from locale code to the translated text in each locale. One translation must be provided. Currently, we do not support additional translations. When displaying text, we will first attempt to use the translation for the locale used by the user’s device, then, if not found, the restaurant’s locale, and finally the default locale for the city. If none of these are found, the first locale listed will be used. Locale codes should specify both language and country codes, e.g. "en-us", "ar-ae"
    - `classifications` Classification[], required
    - `imageUrl` string: (optional) URL pointing to an image of the item. <br/>Image requirements <br/>- File size must be less than 2MB. <br/>- Image must be in JPEG, PNG. <br/>- Optimal resolution for the images will be 800x800 px.
    - `priceInfo` PriceInfo, required: Specifies the price to charge for ordering the item. Price should always be integer value (never decimals) because the price is set in lowest denomination (e.g., cents for US currency, not dollars).Price should always be set even if price is 0.
      - `price` integer, required
    - `externalData` string: (optional) Free-form text field reserved for the api consumer to use.
    - `modifierGroups` string[]: List of modifier groups
    - `quantityInfo` QuantityInfo: Constrains the quantities in which the item can be ordered.
      - `maxPermitted` integer: Maximum permitted value
      - `minPermitted` integer: Minimum permitted value. This cannot exceed the maximum permitted value
    - `nutritionalInfo` NutritionalInfo: This object retains all nutritional information for items and modifiers.
      - `energyInfo` EnergyInfo
        - `amount` string: Holds the calorie count for the respective item or modifier.
        - `unit` string: Specifies the unit of measurement for the calorie count. Currently, only kcal is supported.
    - `type` 'ITEM' | 'MODIFIER', required: item type
    - `availability` 'AVAILABLE' | 'UNAVAILABLE' | 'HIDDEN', required: Availability types for an item
    - `overrides` Override[]: List of context-specific overrides that allow platform-based for the item or modifier.
      - `contextId` string, required: Identifier of the context (defined in the root contexts array) where this override should be applied.
      - `properties` OverrideProperties, required: Represents a context-based override that allows an item or modifier to apply custom properties, such as platform-specific pricing.
        - `price` integer, required: Specifies the override price to charge for the item or modifier in the given context. Prices must be provided as an integer in the lowest currency denomination (e.g., cents), and should always be included even if the value is 0.
  - `modifierGroups` ModifierGroup[], required: List of modifier groups in the menu.
    - `id` string, required: Unique id attribute of the modifier group
    - `name` MultiLingualText, required: Content for a string displayed to users in multiple languages <br/> Supported laguages (Locale ids) <br/> * en-us :- English (United States) <br/> * ar-ae :- Arabic (United Arab Emirates)
      - `translations` Translations, required: A mapping from locale code to the translated text in each locale. One translation must be provided. Currently, we do not support additional translations. When displaying text, we will first attempt to use the translation for the locale used by the user’s device, then, if not found, the restaurant’s locale, and finally the default locale for the city. If none of these are found, the first locale listed will be used. Locale codes should specify both language and country codes, e.g. "en-us", "ar-ae"
    - `quantityInfo` QuantityInfo, required: Constrains the quantities in which the item can be ordered.
      - `maxPermitted` integer: Maximum permitted value
      - `minPermitted` integer: Minimum permitted value. This cannot exceed the maximum permitted value
    - `modifiers` string[], required: List of modifiers which are allowed to select with items
  - `categories` Category[], required: List of categories in the menu.
    - `id` string, required: A unique identifying string for the category, provided by the restaurant.
    - `background` CategoryBackground, required: Defines the backgorund of an item. Ex- Image or solid color
      - `type` 'IMAGE' | 'SOLID_COLOR', required: Item background type
      - `value` string, required: item background for an item. Ex- if the type is IMAGE, then the value will be an uri, else color code
    - `name` MultiLingualText, required: Content for a string displayed to users in multiple languages <br/> Supported laguages (Locale ids) <br/> * en-us :- English (United States) <br/> * ar-ae :- Arabic (United Arab Emirates)
      - `translations` Translations, required: A mapping from locale code to the translated text in each locale. One translation must be provided. Currently, we do not support additional translations. When displaying text, we will first attempt to use the translation for the locale used by the user’s device, then, if not found, the restaurant’s locale, and finally the default locale for the city. If none of these are found, the first locale listed will be used. Locale codes should specify both language and country codes, e.g. "en-us", "ar-ae"
    - `description` MultiLingualText: Content for a string displayed to users in multiple languages <br/> Supported laguages (Locale ids) <br/> * en-us :- English (United States) <br/> * ar-ae :- Arabic (United Arab Emirates)
      - `translations` Translations, required: A mapping from locale code to the translated text in each locale. One translation must be provided. Currently, we do not support additional translations. When displaying text, we will first attempt to use the translation for the locale used by the user’s device, then, if not found, the restaurant’s locale, and finally the default locale for the city. If none of these are found, the first locale listed will be used. Locale codes should specify both language and country codes, e.g. "en-us", "ar-ae"
    - `servingHours` ServingHours[], required
      - `dayOfWeek` 'MONDAY' | 'TUESDAY' | 'WEDNESDAY' | 'THURSDAY' | 'FRIDAY' | 'SATURDAY' | 'SUNDAY', required: Days of the week
      - `timePeriods` TimePeriod[], required: The continuous time spans which the items are available.
        - `start` string, required: The time at which the menu becomes available, in 24-hour HH:MM format, e.g. “08:30”, “23:00”
        - `end` string, required: The time at which the menu ceases to be available, in 24-hour HH:MM format, e.g. “08:30”, “23:00”
    - `items` string[], required: List of ids of the top-level menu items available for sale within the category - all items must be of type “ITEM”
  - `contexts` Contexts[]: Collection of context definitions used to apply platform-specific overrides for items and modifiers.
    - Context[]
      - `id` string, required: Unique identifier for the context, referenced in item and modifier overrides.
      - `ranges` Range[], required: List of platform ranges that specify which aggregator channels this context applies to.
        - `type` 'PLATFORM', required: Scope type for the range. Currently only PLATFORM is supported.
        - `ids` string[], required: List of aggregator platform identifiers this context applies to

## Response `200`

Successful response OK

- MenuResponse: Response object of the successful menu publish
  - `id` string, required: Unique id for the menu.
  - `externalReferenceId` string, required: Grubtech unique id for the menu

## Other responses

- `400`: Bad request
- `500`: Internal server error

---

[API](https://skmtc.dev/grubtech/apis/grubtech-menu-api.md) - [All operations](https://skmtc.dev/grubtech/apis/grubtech-menu-api/llms.txt) - [OpenAPI document](https://skmtc.dev/grubtech/apis/grubtech-menu-api/revisions/c569b24d4c3b?raw)
