# Menu Synchronization This endpoint enables menu synchronization for stores on Keeta. The system performs full-menu updates based on the provided data, implementing entity matching through the openItemCode field. App-level throttling: 1. The system identifies entities as follows: - : When matching openItemCode values exist in the store's current menu - : When no matching openItemCode values are found - : All existing entities with openItemCode values not present in the request A successful response only confirms successful submission of the synchronization task. Certain items may still fail during processing due to validation rules, requiring manual verification and resubmission by the caller. The endpoints supports standard HTTP/HTTPS (ports 80/443) external image URLs, which must comply with platform specifications regarding size, format, and accessibility. : | | | | --- | --- | | | - The openItemCode field is mandatory and must maintain uniqueness across entities- Each store cannot exceed 100 menu categories- Category names must be unique within a single store- Only one mandatory category is permitted per store- Categories become hidden when all contained products are delisted, and are repositioned when products become temporarily unavailable | | | - The openItemCode field is mandatory with entity-level uniqueness- Maximum 2,000 option groups per store- Maximum 10,000 options per store- Use the relatedSpuOpenItemCode to explicitly bind the ChoiceGroupSku to an existing SPU entity- Use the relatedSkuOpenItemCode to explicitly bind the ChoiceGroupSku to an existing SKU entity. When the ChoiceGroupSku binds to a SKU, it will use the bounded SKU''s ChoiceGroups to form a multi-layer ChoiceGroup structure.- When both relatedSkuOpenItemCode and relatedSpuOpenItemCode are declared, there will be a association check to ensure the SKU belongs to the declared SPU.- If both relatedSpuOpenItemCode and relatedSkuOpenItemCode are not specified, automatic binding occurs when the ChoiceGroupSku name matches a SPU name, enabling coordinated SPUs and ChoiceGroupSku status management(Note: If multiple SPUs share identical names, the system randomly selects one for binding, which may lead to unintended synchronization.)- External image URLs are supported in the pictureList field | | | - The openItemCode field is mandatory with entity-level uniqueness- Maximum 2,000 SPUs per store- Maximum 15 featured products per store- Tobacco/alcohol products must have corresponding attributes marked as "Yes"- External image URLs are supported in the pictureList field- Time-limited availability slots cannot overlap and are limited to 30 time periods- The shopCategoryOpenItemCodeList request should include the menu category openItemCode which exists in the specific store- The choiceGroupOpenItemCodeList request should include the choicegroup openItemCode which exists in the specific store | | | - Optional field that defaults to upload sequence when empty- Requires complete sorting data for all products across all categories when provided | Endpoint: POST /product/menu/sync Version: v.1.0.0 ## Request fields (application/json): - `shopId` (integer, required) Unique identifier of the Keeta store. Example: 12345 - `shopCategoryList` (array, required) Please send all the menu category info of the specific store to this field. - `shopCategoryList.id` (integer) Keeta's menu category ID. Not required for OpenItemCode-based APIs. Required for updates in Keeta ID-based APIs. Example: 12345 - `shopCategoryList.name` (string, required) Name of the category in a menu Example: "Happy Meal" - `shopCategoryList.sourceLanguageType` (string, required) Language type of the name field. Supported language enums can be found in Menu Integration Guide Example: "en" - `shopCategoryList.nameTranslation` (string) Translated text for the name field Example: "開心樂園餐" - `shopCategoryList.targetLanguageType` (string) Language type of nameTranslation. Required when nameTranslation is provided. Example: "zh-HK" - `shopCategoryList.nameTranslateType` (integer) Source of name translation. When the value equals 1, it indicates that the name translation was provided by the merchant. Example: 1 - `shopCategoryList.type` (integer, required) Indicates the menu category type: - `shopCategoryList.description` (string) Brief description of the category in a menu Example: "Happy Meal description" - `shopCategoryList.descSourceLanguageType` (string) Language type of description. Required if description exists. Example: "en" - `shopCategoryList.descriptionTranslation` (string) Translated text for description Example: "開心樂園餐描述" - `shopCategoryList.descTargetLanguageType` (string) Language type of descriptionTranslation. Required when descriptionTranslation exists. Example: "zh-HK" - `shopCategoryList.descriptionTranslateType` (integer) Source of description translation. When the value equals 1, it indicates that the description translation was provided by the merchant. Example: 1 - `shopCategoryList.openItemCode` (string, required) Third-party category ID. Mandatory and must be unique in OpenItemCode-based APIs. Optional in Keeta ID-based APIs. Example: "SHOP_CATEGORY#10001" - `shopCategoryList.availableTime` (object) Selling time slots for this category. Categories are unavailable outside these times. - `shopCategoryList.availableTime.code` (integer, required) Selling time type indicator: - `shopCategoryList.availableTime.values` (array) Required when code=1. Contains 7 strings representing daily time slots (Sunday to Saturday). Empty string means unavailable. - `shopCategoryList.availableTime.available` (array) Defines specific date ranges and time windows. Required when code=2. - `shopCategoryList.availableTime.available.startTimestamp` (integer) Beginning timestamp (milliseconds). Required when using absolute date ranges. If set without endTimestamp, indicates perpetual availability after start date. Required when AvailableTime.code = 2 Example: 1735660800000 - `shopCategoryList.availableTime.available.endTimestamp` (integer) Ending timestamp (milliseconds). When omitted with startTimestamp, creates open-ended availability. Example: 1736956799000 - `choiceGroupList` (array, required) Please send all the choicegroup info of the specific store to this field. - `choiceGroupList.id` (integer) Unique ChoiceGroup ID generated by Keeta system. Not required in OpenItemCode-based APIs. Required for updates in Keeta ID-based APIs. - `choiceGroupList.name` (string, required) Display name of the ChoiceGroup Example: "Sauces" - `choiceGroupList.sourceLanguageType` (string, required) Language code for name field (refer to Menu Integration Guide) Example: "en" - `choiceGroupList.nameTranslation` (string) Localized name translation Example: "選擇醬料" - `choiceGroupList.targetLanguageType` (string) Language code for nameTranslation (required if translation exists), please refer to [Menu API Integration Guide](./docs/menuIntegrationGuide.md) Example: "zh-HK" - `choiceGroupList.minNumber` (integer, required) Minimum number of ChoiceGroupSkus that must be selected - `choiceGroupList.maxNumber` (integer, required) Maximum number of ChoiceGroupSkus that can be selected Example: 3 - `choiceGroupList.choiceGroupSkuList` (array, required) List of available ChoiceGroupSkus in this ChoiceGroup - `choiceGroupList.choiceGroupSkuList.id` (integer) Primary key for ChoiceGroupSku, mainly used for order API alignment. Changes when names are modified. Not required in OpenItemCode-based APIs. Required for updates in Keeta ID-based APIs. - `choiceGroupList.choiceGroupSkuList.name` (string, required) Display name of the ChoiceGroupSku. Should match SPU name when representing the same product for internal correlation. Example: "Ketchup" - `choiceGroupList.choiceGroupSkuList.price` (string) Delivery price (supports 2 decimal places) Example: "12.33" - `choiceGroupList.choiceGroupSkuList.pickPrice` (string) Pickup price (supports 2 decimal places) Example: "12.33" - `choiceGroupList.choiceGroupSkuList.canteenPrice` (string) Dine-in price (supports 2 decimal places) Example: "12.33" - `choiceGroupList.choiceGroupSkuList.currency` (string) Currency code (refer to "Currency Symbols" enum). Defaults to merchant's currency. Example: "HKD" - `choiceGroupList.choiceGroupSkuList.status` (integer, required) Availability status: > 0: indicates the ChoiceGroupSku is unavailable / > 1: indicates ChoiceGroupSku is available Example: 1 - `choiceGroupList.choiceGroupSkuList.openItemCode` (string, required) Third-party ChoiceGroupSku identifier. Mandatory and unique in OpenItemCode-based APIs. Example: "CHOICE#10001" - `choiceGroupList.choiceGroupSkuList.nutritionalInfo` (object) Nutritional components (refer to "Nutritional Elements" enum) - `choiceGroupList.choiceGroupSkuList.allergens` (array) Allergen information (refer to "Allergens" enum) - `choiceGroupList.choiceGroupSkuList.pictureList` (array) ChoiceGroupSku image URLs - `choiceGroupList.choiceGroupSkuList.pictureList.url` (string, required) ChoiceGroupSku image URLs Example: "https://img-ap-hongkong.mykeeta.net/sailorproduct/9c760595674b395e330cf94b0e5068b09999.jpg" - `choiceGroupList.choiceGroupSkuList.relatedSpuOpenItemCode` (string) Third-party SPU identifier this ChoiceGroupSku should bind to. Using this to explicitly bind the ChoiceGroupSku to the given SPU. - `choiceGroupList.choiceGroupSkuList.relatedSkuOpenItemCode` (string) Third-party SKU identifier this ChoiceGroupSku should bind to. Using this to explicitly bind the ChoiceGroupSku to the given SKU. When a ChoiceGroupSku bind to a SKU, it will use the bounded SKU's ChoiceGroups to form a multi-layer ChoiceGroup structure. - `choiceGroupList.openItemCode` (string, required) Developer-provided ChoiceGroup identifier. Mandatory and unique in OpenItemCode-based APIs. Example: "GROUP#10001" - `choiceGroupList.repeatable` (integer) Multiple selection flag: - `spuList` (array, required) Please send all the SKU info of the specific store to this field. - `spuList.id` (integer) Unique SPU ID generated by Keeta. Not required in OpenItemCode-based APIs. Required for updates in Keeta ID-based APIs. See "Menu Development Guide" for details. Example: 12345 - `spuList.name` (string, required) Product name Example: "Spicy Chicken Burger" - `spuList.status` (integer, required) Product availability status: Example: 1 - `spuList.description` (string) Product description Example: "Spicy Chicken Burger description" - `spuList.descSourceLanguageType` (string) Language code for description (required if description exists), please refer to [Menu API Integration Guide](./docs/menuIntegrationGuide.md) Example: "en" - `spuList.descriptionTranslation` (string) Localized description translation Example: "辣雞腿漢堡描述" - `spuList.descTargetLanguageType` (string) Language code for descriptionTranslation (required if translation exists), please refer to [Menu API Integration Guide](./docs/menuIntegrationGuide.md) Example: "zh-HK" - `spuList.shopCategoryList` (array) Menu categories this SPU belongs to. The 'id' field is required when not using menuSync API. For all interfaces using this struct except menuSync, the id field in ShopCategory struct is required to associate SPUs with category. - `spuList.pictureList` (array) Product image URLs - `spuList.pictureList.url` (string, required) Product image URLs - `spuList.propertyList` (array) SPU specifications (e.g., "Size" options for pizza) - `spuList.propertyList.propertyId` (integer, required) Unique identifier for the property Example: 9999 - `spuList.propertyList.propertyName` (string) Display name of the property (e.g., "Size" for pizza) - `spuList.propertyList.propertyType` (integer) Property classification: Example: 1 - `spuList.propertyList.minValueNumber` (integer) Minimum number of values that must be selected - `spuList.propertyList.maxValueNumber` (integer) Maximum number of values that can be selected - `spuList.propertyList.customizable` (integer) Custom value allowance: 0: customizable = 0 prohibits custom values 1: customizable = 1 allows custom text input - `spuList.propertyList.propertyValueList` (array, required) List of predefined property values - `spuList.propertyList.propertyValueList.valueId` (integer, required) Unique identifier for the property value Example: 9999 - `spuList.propertyList.propertyValueList.valueName` (string) Display name of the property value (e.g., "Large" for pizza size) - `spuList.skuList` (array, required) A list includes all SKUs under this SPU - `spuList.skuList.id` (integer) Unique SKU ID generated by Keeta system. Not required in OpenItemCode-based APIs. Required for updates in Keeta ID-based APIs. For details, see "Menu Development Guide" for details. Example: 12345 - `spuList.skuList.spec` (string) Specification name (optional for single-spec products) Example: "Large" - `spuList.skuList.specTranslation` (string) Localized specification translation Example: "大份" - `spuList.skuList.targetLanguageType` (string) Language code for specTranslation (required if translation exists), please refer to [Menu API Integration Guide](./docs/menuIntegrationGuide.md) Example: "zh-HK" - `spuList.skuList.specTranslateType` (string) Source of spec translation. When the value equals 1, it indicates that the spec translation was provided by the merchant. Example: "1" - `spuList.skuList.price` (string) Delivery price (supports 3 decimal places, e.g. "12.33") Example: "28.0" - `spuList.skuList.pickPrice` (string) Pickup price (supports 3 decimal places) Example: "28.0" - `spuList.skuList.canteenPrice` (string) Dine-in price (supports 3 decimal places) Example: "28.0" - `spuList.skuList.currency` (string) Currency code (refer to "Currency Symbols" enum). Defaults to merchant's currency if empty. Example: "HKD" - `spuList.skuList.choiceGroupList` (array) List of ChoiceGroups associated with this SKU. Not used for menuSync API. - `spuList.skuList.openItemCode` (string, required) Developer-provided SKU identifier. Mandatory and unique in OpenItemCode-based APIs. Optional for Keeta-based ID APIs. Example: "SKU#10001" - `spuList.skuList.choiceGroupOpenItemCodeList` (array) OpenItemCodes of associated ChoiceGroups. Required for menuSync API. - `spuList.availableTime` (object, required) Selling time slots for this product - `spuList.isSpecialty` (integer, required) Signature dish indicator: - `spuList.openItemCode` (string, required) Developer-provided SPU identifier. Mandatory and unique in OpenItemCode-based APIs. Example: "SPU#10001" - `spuList.shopCategoryOpenItemCodeList` (array, required) This field contains the OpenItemCodes that correspond to menu categories in Keeta's system. When calling the menu synchronization (menuSync) API, this field becomes mandatory. The OpenItemCodes are provided by developers and maintain a one-to-one relationship with Keeta's internal menu category IDs. The Keeta platform will verify whether these OpenItemCodes actually exist in the merchant's store. Example: ["2$33419","3$34747"] - `spuList.userGetModeList` (array, required) This field specifies the supported order fulfillment modes, with case-sensitive values. By default, all products support "delivery" mode. To enable "pickup" mode, the following conditions must be satisfied: First, every SKU in the skuList must have a valid pickPrice value specified. Second, all options within every choice group associated with these SKUs must also have pickPrice values defined. The system recognizes two mode values: "delivery" for standard food delivery services "pickup" for customer self-collection scenarios Example: ["delivery","pickup"] - `spuSequenceCodeMap` (object) This field allows developers to set product sorting within menu categories. When the value equals null, product sorting follows Keeta's default sorting. : - : Menu category's OpenItemCode - : Array of SPU OpenItemCodes in desired display order Merchants can specify exact product order by listing SPU OpenItemCodes in the desired sequence for each category. The specified order updates the in-app display, showcasing products in the defined arrangement. Example: {"shopCategoryOpenItemCode1":["spuOpenItemCode1","spuOpenItemCode2"],"shopCategoryOpenItemCode2":["spuOpenItemCode1","spuOpenItemCode3"]} ## Response 200 fields (application/json): - `code` (integer, required) A numeric status identifier indicating the result of the interface call, used to determine whether the operation executed successfully. - `message` (string, required) Text description corresponding to the status code, explaining the operation result or error cause to users. Example: "Success" - `data` (integer) When interacting with Keeta's platform for actions that require asynchronous processing, such as complex data operations or system integrations, the platform will initiate a task that may not complete immediately upon request submission. Instead of providing immediate completion confirmation, Keeta's system generates a taskId, which serves as a unique identifier for that specific task in the internal execution system.