Menus
The Menus resource enables you to interact with the menus of your stores.
The following table describes the different contents of the Menus resource:
| Resource | Description |
|---|---|
GET menu | Returns the collection of menus created by the authenticating ally |
POST menu | Creates or updates a menu in a store |
GET menu/approved/{storeId} | Returns the current approval status of a menu |
GET menu/rappi/{storeId} | Returns the last menu created for a store |
GET menu
Use this endpoint to return the collection of menus created by the authenticating ally.
Endpoint URL
Use this URL to make a request with this endpoint:
https://{COUNTRY_DOMAIN}/api/v2/restaurants-integrations-public-api/menu
{COUNTRY_DOMAIN}: This is your Rappi Country Domain. See the list of Country Domains.
Endpoint Properties
This resource has the following properties:
| Response formats | JSON |
| Authentication requirements | Token |
Parameters
This endpoint does not permit additional parameters.
Status Codes
These are the possible status codes of the response for this endpoint:
Sample Request
This is an example of an API request using this endpoint:
GET https://microservices.dev.rappi.com/api/v2/restaurants-integrations-public-api/menu
This is an example of the request:
URL url = new URL("https://microservices.dev.rappi.com/api/v2/restaurants-integrations-public-api/menu"); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("GET"); connection.setRequestProperty("User-Agent", "Mozilla/5.0"); connection.setRequestProperty("Content-Type", "application/json"); connection.setRequestProperty("Accept", "application/json"); connection.setRequestProperty("x-authorization", "Bearer YOUR_TOKEN"); try (BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream(), StandardCharsets.UTF_8))) { StringBuilder response = new StringBuilder(); String responseLine; while ((responseLine = br.readLine()) != null) { response.append(responseLine.trim()); } System.out.println("Response body: " + response.toString()); } System.out.println("Response Code : " + connection.getResponseCode());
Sample Response "Success 200":
This is an example of the response:
[ { "storeId": "900111978", "items": [ { "name": "Naked Cake con frutos", "description": "Naked cake decorado con frutos. Cubierta de trufa derretida (ganache) y decorada con frutos del bosque.", "sku": "8569874", "type": "PRODUCT", "price": 75.0, "category": { "id": "3", "name": "Tortas", "minQty": 0, "maxQty": 0, "sortingPosition": 0 }, "imageUrl": "https://image.com/image1.jpg", "children": [ { "name": "Chocolate", "description": "", "sku": "8569874-159", "type": "TOPPING", "price": 0.0, "category": { "id": "1", "name": "Sabor", "minQty": 0, "maxQty": 1, "sortingPosition": 0 }, "imageUrl": "https://image.com/image10.jpg", "children": [], "rappiIds": ["340948822"], "sortingPosition": 1, "maxLimit": 1 } ], "rappiIds": ["2135527868"], "sortingPosition": 0, "maxLimit": 1 }, { "name": "Snowman", "description": "Linda lata de Snowman con productos variadosIncluye:Galletas mantequilla 350 gr, 6 brookies y 4 trufas de brownie.", "sku": "856887", "type": "PRODUCT", "price": 75.0, "category": { "id": "9", "name": "Navidad", "minQty": 0, "maxQty": 0, "sortingPosition": 0 }, "imageUrl": "https://image.com/image2.jpg", "children": [], "rappiIds": ["2135524472"], "sortingPosition": 0, "maxLimit": 1 } ] } ]
This table describes the objects contained in the response example:
| Response Object | Object Description |
|---|---|
storeIdstring | Identifier of the store in the Rappi application. |
itemsarray of objects | Product list |
items.namestring | Name of the product in the menu |
items.descriptionstring | Description of the product in the menu |
items.skustring | SKU that the ally assigned for the product in the menu |
items.typestring | Item type. In this case can be only PRODUCT |
items.priceinteger | Price of the product in the menu |
items.imageUrlstring | Image url of the product in the menu |
items.rappiIdsarray of string | List of the identifiers Rappi gives to this item |
items.sortingPositioninteger | The position of the product in its category |
items.maxLimitinteger | Maximum indicator of the item, it's required only if the type is topping |
items.categorystring | Category of the product in the menu |
items.category.idstring | The SKU (Stock-Keeping Unit) the ally gives to this category |
items.category.namestring | Category name |
items.category.minQtyinteger | The maximum number of items that can be ordered in this category |
items.category.maxQtyinteger | The minimum quantity of elements that can be ordered in this category (In toppings, if it's 0 it means that it's not mandatory) |
items.category.sortingPositioninteger | it's the position of the category in the menu |
items.childrenarray of objects | List of product's toppings from the menu |
items.children.namestring | Name of the topping in the menu |
items.children.descriptionstring | Description of the topping in the menu |
items.children.skustring | SKU that the ally assigned for the topping in the menu |
items.children.typestring | Item type. In this case can be only TOPPING |
items.children.priceinteger | Price of the topping in the menu |
items.children.imageUrlstring | Image url of the topping in the menu |
items.children.rappiIdsarray of string | List of the identifiers Rappi gives to this item |
items.children.sortingPositioninteger | The position of the topping in its category |
items.children.maxLimitinteger | Maximum indicator of the item, it's required only if the type is topping |
items.children.categorystring | Category of the topping in the menu |
items.children.category.idstring | The SKU (Stock-Keeping Unit) the ally gives to this category |
items.children.category.namestring | Category name |
items.children.category.minQtyinteger | The maximum number of items that can be ordered in this category |
items.children.category.maxQtyinteger | The minimum quantity of elements that can be ordered in this category (In toppings, if it's 0 it means that it's not mandatory) |
items.children.category.sortingPositioninteger | The position of the category within the product |
Sample Response "Invalid credentials 401":
{ "message": "Not a valid token" }
This table describes the attributes from JSON response:
| Attributes | Description |
|---|---|
messagestring | Not a valid token |
POST menu
Use this endpoint to create a new menu, or to add new items to an existing one, for the authenticated ally.
After creating a menu, or adding new items to an existing one, the Rappi team validates the items and the structure of the menu. You can consult the status of the approval process by using the GET menu/approved/{storeId} endpoint.
Endpoint URL
Use this URL to make a request with this endpoint:
https://{COUNTRY_DOMAIN}/api/v2/restaurants-integrations-public-api/menu
{COUNTRY_DOMAIN}: This is your Rappi Country Domain. See the list of Country Domains.
Endpoint Properties
This resource has the following properties:
| Response formats | JSON |
| Request body requirements | JSON |
| Authentication requirements | Token |
Parameters
This endpoint does not permit additional parameters.
Status Codes
These are the possible status codes of the response for this endpoint:
Sample Request
This is an example of an API request using this endpoint:
POST https://microservices.dev.rappi.com/api/v2/restaurants-integrations-public-api/menu
This is an example of the request:
{ "storeId": "900103361", "items": [ { "category": { "id": "2090019638", "maxQty": 0, "minQty": 0, "name": "Burgers", "sortingPosition": 0 }, "children": [ { "category": { "id": "211", "maxQty": 1, "minQty": 0, "name": "Do you want to add?", "sortingPosition": 0 }, "children": [], "name": "French Fries", "price": 5000, "sku": "2135092195", "sortingPosition": 1, "type": "TOPPING", "maxLimit": 1 }, { "category": { "id": "211", "maxQty": 1, "minQty": 0, "name": "Do you want to add?", "sortingPosition": 0 }, "children": [], "name": "Potato Wedges", "price": 7000, "sku": "2135092196", "sortingPosition": 1, "type": "TOPPING", "maxLimit": 1 } ], "name": "Grilled Chicken Burger", "price": 14000, "sku": "2135092197", "sortingPosition": 0, "type": "PRODUCT", "combo": true }, { "category": { "id": "2090019639", "maxQty": 0, "minQty": 0, "name": "Pizzas", "sortingPosition": 1 }, "children": [], "name": "Hawaiian Pizza", "price": 17000, "sku": "2135092198", "sortingPosition": 1, "type": "PRODUCT", "combo": true } ] }
URL url = new URL("https://microservices.dev.rappi.com/api/v2/restaurants-integrations-public-api/menu"); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("POST"); connection.setRequestProperty("User-Agent", "Mozilla/5.0"); connection.setRequestProperty("Content-Type", "application/json"); connection.setRequestProperty("Accept", "application/json"); connection.setRequestProperty("x-authorization", "Bearer YOUR_TOKEN"); connection.setDoOutput(true); String jsonInputString = "{\n" + " \"storeId\": \"900103361\",\n" + " \"items\": [\n" + " {\n" + " \"category\": {\n" + " \"id\": \"2090019638\",\n" + " \"maxQty\": 0,\n" + " \"minQty\": 0,\n" + " \"name\": \"Burgers\",\n" + " \"sortingPosition\": 0\n" + " },\n" + " \"children\": [\n" + " {\n" + " \"category\": {\n" + " \"id\": \"211\",\n" + " \"maxQty\": 1,\n" + " \"minQty\": 0,\n" + " \"name\": \"Do you want to add?\",\n" + " \"sortingPosition\": 0\n" + " },\n" + " \"children\": [],\n" + " \"name\": \"French Fries\",\n" + " \"price\": 5000,\n" + " \"sku\": \"2135092145\",\n" + " \"sortingPosition\": 1,\n" + " \"type\": \"TOPPING\",\n" + " \"maxLimit\": 1\n" + " },\n" + " {\n" + " \"category\": {\n" + " \"id\": \"211\",\n" + " \"maxQty\": 1,\n" + " \"minQty\": 0,\n" + " \"name\": \"Do you want to add?\",\n" + " \"sortingPosition\": 0\n" + " },\n" + " \"children\": [],\n" + " \"name\": \"Potato Wedges\",\n" + " \"price\": 7000,\n" + " \"sku\": \"2135092145\",\n" + " \"sortingPosition\": 1,\n" + " \"type\": \"TOPPING\",\n" + " \"maxLimit\": 1\n" + " }\n" + " ],\n" + " \"name\": \"Grilled Chicken Burger\",\n" + " \"price\": 14000,\n" + " \"sku\": \"2135092145\",\n" + " \"sortingPosition\": 0,\n" + " \"type\": \"PRODUCT\"\n" + " \"combo\": true\n" + " },\n" + " {\n" + " \"category\": {\n" + " \"id\": \"2090019639\",\n" + " \"maxQty\": 0,\n" + " \"minQty\": 0,\n" + " \"name\": \"Pizzas\",\n" + " \"sortingPosition\": 1\n" + " },\n" + " \"children\": [],\n" + " \"name\": \"Hawaiian Pizza\",\n" + " \"price\": 17000,\n" + " \"sku\": \"2135092145\",\n" + " \"sortingPosition\": 1,\n" + " \"type\": \"PRODUCT\"\n" + " \"combo\": true\n" + " }\n" + " ]\n" + "}\n"; try (OutputStream os = connection.getOutputStream()) { byte[] input = jsonInputString.getBytes(StandardCharsets.UTF_8); os.write(input, 0, input.length); } try (BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream(), StandardCharsets.UTF_8))) { StringBuilder response = new StringBuilder(); String responseLine; while ((responseLine = br.readLine()) != null) { response.append(responseLine.trim()); } System.out.println("Response body: " + response.toString()); } System.out.println("Response Code : " + connection.getResponseCode());
This table describes the attributes that the JSON of your request requires:
| Attributes | Requirement | Description |
|---|---|---|
storeIdstring | required | Identifier of the store in the Rappi application. |
itemsarray of objects | required | Product list |
items.namestring | required | Name of the product in the menu |
items.descriptionstring | required | Description of the product in the menu |
items.skustring | required | SKU that the ally assigned for the product in the menu |
items.typestring | required | Item type. In this case can be only PRODUCT |
items.priceinteger | required | Price of the product in the menu |
items.imageUrlstring | optional | Image url of the product in the menu |
items.rappiIdsarray of string | optional | List of the identifiers Rappi gives to this item |
items.sortingPositioninteger | optional | The position of the product in its category |
items.maxLimitinteger | optional | Maximum indicator of the item, it's required only if the type is topping |
items.comboboolean | optional | Indicates if the element belongs to a combo |
items.categorystring | required | Category of the product in the menu |
items.category.idstring | required | The SKU (Stock-Keeping Unit) the ally gives to this category |
items.category.namestring | required | Category name |
items.category.minQtyinteger | required | The maximum number of items that can be ordered in this category |
items.category.maxQtyinteger | required | The minimum quantity of elements that can be ordered in this category (In toppings, if it's 0 it means that it's not mandatory) |
items.category.sortingPositioninteger | required | it's the position of the category in the menu |
items.childrenarray of objects | optional | List of product's toppings from the menu |
items.children.namestring | required | Name of the topping in the menu |
items.children.descriptionstring | required | Description of the topping in the menu |
items.children.skustring | required | SKU that the ally assigned for the topping in the menu |
items.children.typestring | required | Item type. In this case can be only TOPPING |
items.children.priceinteger | required | Price of the topping in the menu |
items.children.imageUrlstring | optional | Image url of the topping in the menu |
items.children.rappiIdsarray of string | optional | List of the identifiers Rappi gives to this item |
items.children.sortingPositioninteger | optional | The position of the topping in its category |
items.children.maxLimitinteger | optional | Maximum indicator of the item, it's required only if the type is topping |
items.children.categorystring | required | Category of the topping in the menu |
items.children.category.idstring | required | The SKU (Stock-Keeping Unit) the ally gives to this category |
items.children.category.namestring | required | Category name |
items.children.category.minQtyinteger | required | The maximum number of items that can be ordered in this category |
items.children.category.maxQtyinteger | required | The minimum quantity of elements that can be ordered in this category (In toppings, if it's 0 it means that it's not mandatory) |
items.children.category.sortingPositioninteger | required | The position of the category within the product |
Sample response "200 success"
This endpoint returns only one successful response code.
Sample response "400 The menu structure is invalid"
400 The menu structure is invalid:
{ "message": "The submitted menu has errors.", "errors": [ { "reason": "All items must have a valid name, category or product description.", "relatedItems": [ { "description": "", "sku": "product1", "type": "PRODUCT", "price": 899.0, "category": { "id": "455", "name": "producto category name 1", "minQty": 0, "maxQty": 0, "sortingPosition": 0 }, "imageUrl": "https://anydomain/anyimagen_1.png", "rappiIds": ["1965855"], "sortingPosition": 0, "maxLimit": 1 } ] }, { "reason": "Invalid urls were found", "relatedItems": [ { "name": "producto name 1", "description": "", "sku": "product2", "type": "PRODUCT", "price": 899.0, "category": { "id": "455", "name": "producto category name 1", "minQty": 0, "maxQty": 0, "sortingPosition": 0 }, "imageUrl": "httpaas://anydomain/anyimagen_2.png", "rappiIds": ["1965855"], "sortingPosition": 0, "maxLimit": 1 } ] } ] }
This table describes the attributes from JSON response:
| Attributes | Description |
|---|---|
messagestring | Generic error message to response "structure is invalid." message: "The submitted menu has errors." |
errorsarray of objects | Error list found in menu. |
errors.reasonstring | Description of the error. you can find more info in "Validations on the Received menu" |
errors.relatedItemsarray of objects | Items with error. |
You can see the list of structure validations in the VALIDATIONS ON THE RECEIVED MENU.
Sample response "401 Invalid Credentials"
401 Invalid Credentials:
{ "message": "Not a valid token" }
This table describes the attributes from JSON response:
| Attributes | Description |
|---|---|
messagestring | Not a valid token |
Sample response "404 Store not found"
404 Store not found:
{ "message": "StoreId 9001035324: not found associated Stores" }
This table describes the attributes from JSON response:
| Attributes | Description |
|---|---|
messagestring | Store not found |
Sample response "500 Internal server error"
500 Internal server error:
{ "message": "An error occurred while processing your request. please try again later.", "detail": { "error": { "code": "catalog_error_code", "message": "Description of the error received from the catalog service" } } }
This table describes the attributes from JSON response:
| Attributes | Description |
|---|---|
messagestring | Generic error message indicating the request could not be processed. |
detailobject | string | null | Raw error detail forwarded from the internal menu service. Contains the error returned by the catalog service when available. Can be a JSON object, a plain string, or null if no detail is available. |
detail.errorobject | Error object from the internal service. |
detail.error.codestring | Error code identifier from the catalog service. |
detail.error.messagestring | Human-readable description of the error from the catalog service. |
Sample response "424 Failed Dependency"
424 Failed Dependency:
{ "message": "An error occurred while processing your request. please try again later.", "detail": { "error": { "code": "duplicated_items_complies", "message": "There are duplicate products within the same category or modifier group. Please remove the duplicates." } } }
This table describes the attributes from JSON response:
| Attributes | Description |
|---|---|
messagestring | Generic error message indicating the request could not be processed. |
detailobject | string | null | Raw error detail forwarded from the internal menu service. Contains the error returned by the catalog service when available. Can be a JSON object, a plain string, or null if no detail is available. |
detail.errorobject | Error object from the internal service. |
detail.error.codestring | Validation code identifying the specific error from the catalog service. See the table below for possible values. |
detail.error.messagestring | Human-readable description of the error from the catalog service. |
Catalog validation codes
| Code | Type | Description |
|---|---|---|
duplicated_categories_complies | Structural | There are duplicate categories in the menu. Please check that each category has a unique name and code. |
duplicated_items_complies | Structural | There are duplicate products within the same category or modifier group. Please remove the duplicates. |
item_relation_complies | Structural | The menu structure has an error: a product is directly linked to another product, or a modifier group to another group. Please review the hierarchy. |
item_relation_without_cyclic_complies | Structural | A loop was detected in the menu structure: a product appears more than once in the same path. This can cause errors when navigating the menu. |
start_and_ends_with_item | Structural | The menu path does not start or end with a product. Each path must begin and end with a product, not a modifier group. |
minimum_menus_complies | Structural | No menu was found for the store. At least one menu is required to publish. |
minimum_categories_complies | Structural | No category was found in the menu. At least one category is required. |
minimum_items_complies | Structural | No product was found in the menu. At least one product is required. |
image_url_complies | Content | The product image URL is not valid. Make sure it starts with http:// or https:// and does not contain spaces. |
text_format_complies | Content | The text contains emojis or forbidden words, which are not allowed in the product or category name, description, or code. |
text_fields_length_complies | Content | The product/category name or code is empty, too short, or too long. All products and categories must have a name and code within the allowed length limits. |
override_type_complies | Content | An invalid customization type was used on the product. Please review the product override settings. |
positive_numbers_complies | Content | The product price or quantities are negative, or a modifier group has maximum allowed quantity set to zero. These values must be positive. |
min_permitted_complies | Content | A standard product has a minimum required quantity greater than zero. Standard products should not require a minimum quantity. |
zero_price_complies | Content | The product price is zero. Please make sure all products have an assigned price. |
max_item_childs_complies | Limits | The product or modifier group has too many child items (more than 50). Please reduce the number of options. |
max_item_images_complies | Limits | The product has too many images (more than 3). Please reduce the number of images per product. |
max_item_level_depth_complies | Limits | The menu structure has too many nesting levels. The limit is 11 levels. Please simplify the modifier structure. |
max_items_category_complies | Limits | The category has too many products (more than 50). Please split the products into multiple categories. |
max_time_periods_complies | Limits | The product or category has too many configured time periods (more than 6 per day). Please reduce the number of time slots. |
max_permitted_in_items_complies | Limits | The sum of maximum allowed quantities for child products is not valid. Please review the quantities set in the modifier group. |
GET menu/approved/{storeId}
Use this endpoint to return the approval status of a menu.
Endpoint URL
Use this URL to make a request with this endpoint:
https://{COUNTRY_DOMAIN}/api/v2/restaurants-integrations-public-api/menu/approved/{storeId}
{COUNTRY_DOMAIN}: This is your Rappi Country Domain. See the list of Country Domains.
Endpoint Properties
This resource has the following properties:
| Response formats | JSON |
| Authentication requirements | Token |
Parameters
This endpoint does not permit additional parameters.
Status Codes
This table contains the possible response codes for this endpoint:
Sample Request
This is an example of an API request using this endpoint:
GET https://microservices.dev.rappi.com/api/v2/restaurants-integrations-public-api/menu/approved/251
This is an example of the request:
final Integer storeId = 251; URL url = new URL(String.format("https://microservices.dev.rappi.com/api/v2/restaurants-integrations-public-api/menu/approved/%s", storeId)); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("GET"); connection.setRequestProperty("User-Agent", "Mozilla/5.0"); connection.setRequestProperty("Content-Type", "application/json"); connection.setRequestProperty("Accept", "application/json"); connection.setRequestProperty("x-authorization", "Bearer YOUR_TOKEN"); try (BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream(), StandardCharsets.UTF_8))) { StringBuilder response = new StringBuilder(); String responseLine; while ((responseLine = br.readLine()) != null) { response.append(responseLine.trim()); } System.out.println("Response body: " + response.toString()); } System.out.println("Response Code : " + connection.getResponseCode());
Sample Response
This endpoint returns a status response code only.
401 Invalid Credentials:
{ "message": "Not a valid token" }
GET menu/rappi/{storeId}
Use this endpoint to return the last menu created for a specific store.
Endpoint URL
Use this URL to make a request with this endpoint:
https://{COUNTRY_DOMAIN}/api/v2/restaurants-integrations-public-api/menu/rappi/{storeId}
{COUNTRY_DOMAIN}: This is your Rappi Country Domain. See the list of Country Domains.{storeId}: This is the identifier of your store integration.
Endpoint Properties
This resource has the following properties:
| Response formats | JSON |
| Authentication requirements | Token |
Parameters
This endpoint does not permit additional parameters.
Status Codes
This table contains the possible response codes for this endpoint:
Sample Request
This is an example of an API request using this endpoint:
GET https://microservices.dev.rappi.com/api/v2/restaurants-integrations-public-api/menu/rappi/251
This is an example of the request:
final Integer storeId = 251; URL url = new URL(String.format("https://microservices.dev.rappi.com/api/v2/restaurants-integrations-public-api/menu/rappi/%s", storeId)); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("GET"); connection.setRequestProperty("User-Agent", "Mozilla/5.0"); connection.setRequestProperty("Content-Type", "application/json"); connection.setRequestProperty("Accept", "application/json"); connection.setRequestProperty("x-authorization", "Bearer YOUR_TOKEN"); try (BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream(), StandardCharsets.UTF_8))) { StringBuilder response = new StringBuilder(); String responseLine; while ((responseLine = br.readLine()) != null) { response.append(responseLine.trim()); } System.out.println("Response body: " + response.toString()); } System.out.println("Response Code : " + connection.getResponseCode());
Sample Response
This is an example of the response "Success 200":
{ "storeId": "900111978", "items": [ { "name": "Naked Cake con frutos", "description": "Naked cake decorado con frutos. Cubierta de trufa derretida (ganache) y decorada con frutos del bosque.", "sku": "8569874", "type": "PRODUCT", "price": 75.0, "category": { "id": "3", "name": "Tortas", "minQty": 0, "maxQty": 0, "sortingPosition": 0 }, "imageUrl": "https://image.com/image1.jpg", "children": [ { "name": "Chocolate", "description": "", "sku": "8569874-159", "type": "TOPPING", "price": 0.0, "category": { "id": "1", "name": "Sabor", "minQty": 0, "maxQty": 1, "sortingPosition": 0 }, "imageUrl": "https://image.com/image10.jpg", "children": [], "rappiIds": ["340948822"], "sortingPosition": 1, "maxLimit": 1 } ], "rappiIds": ["2135527868"], "sortingPosition": 0, "maxLimit": 1 }, { "name": "Snowman", "description": "Linda lata de Snowman con productos variadosIncluye:Galletas mantequilla 350 gr, 6 brookies y 4 trufas de brownie.", "sku": "856887", "type": "PRODUCT", "price": 75.0, "category": { "id": "9", "name": "Navidad", "minQty": 0, "maxQty": 0, "sortingPosition": 0 }, "imageUrl": "https://image.com/image2.jpg", "children": [], "rappiIds": ["2135524472"], "sortingPosition": 0, "maxLimit": 1 } ] }
This is an example of the response "Invalid credentials 401":
{ "message": "Not a valid token" }
The context of the attribute response were mentionend before in Get Menu.
