API Document Reference - https://api-ordering-docs.urbanpiper.com/#managing-catalogue
- What is the purpose of this API?
- This API is used to create/update the menu catalogue such as — categories, sub-categories, items, option groups, options, taxes, charges in the UrbanPiper system.
- Should this API be called for a bulk request?
- Yes. It is expected to sync all the available online selling catalogue's data of a brand in a single API request. That means if there are any new catalogue entities got created in bulk or updated in bulk, it is expected that all the changes are saved locally and make a single API request to the UrbanPiper system binding all the objects of the catalogue entities in the payload. This is also called "Bulk upload of data in a single API request".If only one catalogue entity got updated with changes or only one catalogue entity got created, only that particular catalogue entity data to be sent in the API request.
- What is a Federated menu structure?
- The menu catalogue details should be maintained with the same POS reference ids across all the locations of the same brand. POS partners must make sure they have the federated menu structure in place before consuming this API.
- What is the Global/Master/Base level API request?
- This refers to making the menu catalogue API request by setting the location_ref_id to -1 value in the request URL.
- example: https://pos-int.urbanpiper.com/external/api/v1/inventory/locations/-1/
- What is the location level API request?
- This refers to making the menu catalogue API request by setting the location_ref_id to POS location/store id in the request URL.
- example: https://pos-int.urbanpiper.com/external/api/v1/inventory/locations/xyz/
- How flush_operations works for Master-level vs Location-level request?
- "flush_categories": true - This will make the previously synced categories inactive and disassociate all from the location association (if any). It will consider the payload data of categories passed in the same request and keeps only those in the active state.
- "flush_items": true - This will make all the exiting items data inactive keeping only the newly created one in an active state and disassociate all the items from location association.
- "flush_option_groups": true - This will make the previously synced option groups inactive. It will consider the payload data of option groups passed in the same request and keeps only those in the active state.
- "flush_options": true - This will make the previously synced options inactive and disassociate all options data from location association. It will consider the payload data of options passed in the same request and keep only those in the active state.
- "flush_taxes": true and "flush_charges": true - This will make the previously synced taxes and charges inactive. It will consider the payload data of taxes and charges passed in the same request and keeps only those in the active state.
- "flush_categories", "flush_option_groups", "flush_taxes", "flush_charges" passing true will not have any impact while making the location-level API request.
- "flush_items" - This will disassociate all the existing items data from the location/store. It will consider the payload data of the items passed in the same request and keeps only those associated with the location.
"flush_options" - This will disassociate the previously synced options data from the location. It will consider the payload data of the options passed in the same request and keeps only those associated with the location.
- Master-level request
- What is :location_ref_id in the endpoint?
- This holds the POS store ID(for Location-level request) or -1(for Master-level request). Before making an API request for Location-level, make sure that the POS store ID is configured in the Quint Dashboard using Adding/Updating Store API.
- How does the mapping of each menu catalogue happen?
- Categories to items mapping through "category_ref_ids" in Item's array.
- Items to Option Groups mapping through "item_ref_ids" in Option Group's array.
- Option Groups to Options mapping through "opt_grp_ref_ids" in the Options array.
- Taxes and Charges mapping to items through "item_ref_ids" in both the arrays
- How category and sub-category are handled?
- The data inside the "categories" array itself acts as both category and sub-category based on how POS partner define it. The attribute "parent_ref_id" inside a category object determines whether the category should be treated as a parent category or sub-category.
- What is "parent_ref_id" in the Category array?
- If a brand wants to make one category - "B" as a subcategory of another category - "A" then it is expected to keep the POS "ref_id" of the parent category - "A" in the category - "B" object under the attribute "parent_ref_id". Thus, category - "B" becomes the sub-category of parent category - "A".
- What is "category_ref_ids" in the Item array?
- It is the POS system Category id with which the given item should be associated to.
- What is "ref_id" refers to in each menu catalogue array?
- It refers to the POS system generated id of each menu catalogue array in the API request.
- Should it require to send the "translation" array when the default language used is in English?
- No. This "translation" should be sent when the aggregator platforms support regional language on their UI.
Example: For platforms - Talabat, Deliveroo, Jahez who supports the regional language - Arabic, it is expected to send the "translation" for each catalogue entities while syncing the catalogue data when the brand wants to integrate with them,
- Can the same item be associated with multiple categories?
- Yes. Inside the item object, by adding the categories "ref_id"s under the array "category_ref_ids" will associate the same item with multiple categories.
- What is the significance of the "weight" attribute in the Item's array?
- This is used in Meraki and grocery integration to notify the weight of each product. In restaurant integration, this attribute is not used.
- Is it possible to control the real-time inventory numbers through API for aggregators using "current_stock"?
- No. For aggregator integration, maintaining the item stock number isn't supported. Aggregators only consider whether the item is available or not at the present time. It is advised to pass "current_stock": -1 while doing the menu sync. Thus, the item is considered available by default. For Meraki, the item stock numbers are supported.
- While keeping the "current_stock" as -1, how to make item stock-out when the stock goes to 0?
- Using Items Actions API, the item can be disabled on ordering platforms. POS partners can keep the logic in their system such that when an item stock goes less than 2, automatically gives a prompt to make an Items Action API call to disable the item. When the stock is back and is more than 2, give a prompt to make an Items Action API call to enable the item back.
- What is the difference between "sold_at_store" and "available" in the payload?
- "sold_at_store" — The value - true, associates the item to location. The value - false, disassociates the item from the location.
"available" — The value - true, enables the associated item for the store for ordering. The value - false, disables the associated item for the store for ordering. Make sure you keep this in sync with the Item Actions API status.
- What is "markup_price" and how it is different from the regular "price"?
- "price" — The original selling price of the item on the ordering platform.
"markup_price" — The higher value of struck price which is used for running a reduced price offer of an item on ordering platform. (scenario - A merchant wants to sell some items which are slashed to a new lower price due to some offer he is running for the brand. In order to make this offer visible to customers, the merchant specifies the previous higher prices which are struck off to the new lower prices for an item. This information of higher struck price should be passed under "markup_price" and the new lower selling price is passed under the "price" attribute which sold at regular price.)
- What is "external_price" and "price" inside Item's array?
- "external_price" — This attribute is used when the brand is using both Meraki and Hub, and, wants to keep the different price for both the platforms for the same item. The value passed for this attribute is used for Hub. In case both the platforms has got the same item price then passing this attribute would not be required.
- "price" — If both the Hub and Meraki platforms are used and have different prices for the same item then this attribute carries the item price value for the Hub platform. In case both the platforms has got the same item price then passing this attribute would alone is sufficient.
- What is the type of image format to be uploaded under "img_url"?
- Firstly, the image should be hosted on the cloud. That means, it should have the valid https/HTTP URL. Secondly, the image format can be jpg/png and have a file size of less than 50kb each having a dimension of 400*400px.
- How to configure the aggregator platform-specific images?
- You can use the "images": inside Items array to upload the platform-specific item images. Currently, zomato, swiggy, ubereats, amazon are supported.
- Can we configure an item specific for one fulfilment mode alone like delivery, pickup?
- Yes. You can make use of the "fulfillment_modes": for this purpose.
- What are "tags"?
- The tags are the predefined offer list defined by aggregators to put on certain items that the merchant wants to sell on aggregators platform. The tag list will be kept on updating by the aggregators. It is advised to check with the merchant before sending the tags for the items.
- For Swiggy POP items, make sure to add the tag - 'pop' against the item. (when an item is marked with a swiggy 'pop' tag, don't pass the items under taxes and charges "item_ref_ids" array).
- Amazon has got the predefined tag values, make sure you pass the tag value for every item based on the cuisine type. Get the complete list of tag values from your Onboarding Manager.
- What is the difference between "excluded_platforms" and "included_platforms"?
- "excluded_platforms" — This is passed when the item has to be excluded from the passed platform values. For example, "excluded_platforms": ["zomato"] - the item will be hidden for Zomato ordering in UrbanPiper Hub Platform UI. By default, all other aggregators are included for this item in aggregator integration.
- "included_platforms" — This is passed when the item has to be included for the passed platform values. For example, "included_platforms": ["zomato"] - the item is only available for Zomato ordering in UrbanPiper Hub Platform UI. By default, all other aggregators are excluded for this item in aggregator integration.
Note: Make sure you either pass "excluded_platforms" or "included_platforms" for a given item object. Don't pass both.
- How to configure the menu - Pizza>Margherita Pizza>Large Pizza, Medium Pizza, regular and has toppings of tomato, cheese, chicken tikka, etc.?
- PFB the required menu structured.
- Category: Pizza
- Item: Margherita
- Option Group 1: Choose Your Size
- Option Group 2: Choose Your Toppings
- Options associated with Size: Large, Medium, Small
- Options associated with Toppings: Tomato, Cheese, and Chicken
Note: Refer to the shared postman collection
- How to configure the combo items?
-The combo menu can be configured using the items-option group-options using the same above method.
- How to configure the Combo and Combo Groups?
- The support for configuring the aggregator's Combo and Combo Groups are not supported via API.
- Is it possible to assign the same option group for multiple items?
- Yes. But it is advised to keep the distinct Option group "ref_id" for the individual items, i.e, one-to-one combination for items<>OG relation. Thus, it will be easier to deactivate the particular OG for the item using flush_operations when it is decided to no longer continuing the OG for a given item.
- How to disassociate the OG from the items?
- You can make use of the attribute - "clear_item_ref_ids": true inside the Option Groups array. Pass the existing item ref_ids that are associated with the OG that you want to remove by sending the above flag and make a base level request. Followed by, make a master level request with the new combination by sending the item ref_ids in the OG array.
- Is it possible to assign the same option group for multiple options?
- Yes. Again, it is advised to keep the distinct option "ref_id" for the individual option groups, i.e, one-to-one combination for OG<>options relation. Thus, it will be easier to deactivate/disable the particular option for the OG combination using flush_operations when the option is no longer used for the given OG.
- How to disassociate the OG from the items?
- You can make use of the attribute - "clear_opt_grp_ref_ids": true inside the Options array. Pass the existing option group ref_ids that are associated with the Option that you want to remove by sending the above flag and make a base level request. Followed by, make a master level request with the new combination by sending the option group ref_ids in the Option array
- How the "ref_id" mapping of Items-OG-Options expected?
- What are the ways to configure the prices for items and options?
- Price at Item and no-price at options - Given a scenario, it is considered as add-ons, it is not expected to make options as mandatory selectable from the given options group. i.e, the "min_selectable" can be 0 for the option group of this combination.
- No-price at item and price at options - Given the scenario, it is considered as a variant, the options should be made mandatorily selectable from the given option group. i.e, the "min_selectable" should be at least 1 for the option group of this combination.
Price both at item and options - Given the scenario, the options can either made mandatory selectable or optional from a given option group for this combination.
- What is the logic around Create and Updating the menu using this API?
- Let's take an example, create a category A with "ref_id" = "a" and create an item I with "ref_id" = "i". When this data is passed for the very first time, it is treated as a Create event. If the same above menu data is passed again to our system, this is treated as an Update event.
For more info - find Handling certain use-cases under Manage Catalogue API.
- Is there a possibility of having the same item having similar item IDs created in multiple categories?
- Yes. Below are the possible scenarios.
- Scenario-1: If an item is synced without any "category_ref_ids" combination, then only one item having one "ref_id" will be created.
- Scenario-2: If the same item is passed again assigning some "category_ref_ids", then a new item will be created even though having the same item "ref_id" is present in our system.
- Scenario-3: If the same item having the same item "ref_id" setting to some other "category_ref_ids" combination, then one more item with the same item "ref_id" will be created and goes on.
- When the menu sync is done using this API, will it appear in real-time in the aggregator's system?
- Nope. This API just performs the menu population from the POS system to the UrbanPiper system. In order to sync the menu to the aggregator's system, it can be done through Quint Dashboard or through Store Action API API (special case).
- How does the menu sync happen from UrbanPiper to aggregators?
- Zomato, Swiggy, Dunzo, Ubereats, Magicpin, Dotpe, Amazon, Eazydiner: The menu sync will happen from a button push away from Quint Dashboard or through Store Actions API
- Scootsy: The menu will be pulled once in a day.
Talabat: We have to request Talabat team over email once the menu is synced to them from our end. They will update the menu on their end and confirm with us.
- Can items have different prices on different aggregators sites?
- Nope, The prices should be the same across all the aggregators as this is the protocol from the aggregators. The configuration of the differential pricing across aggregators is not supported.
- What is "ref_title" in Items, Option_groups, and Options?
- It is the reference identification title which will help in easy debugging and quick keyword search in quint.
- Do aggregators support nested options for an item?
- Only Zomato and Swiggy supports nested options for an item.
- What is the throttle limit for the API?
- A throttle limit is applicable on this endpoint limiting the maximum of 1 request/5 secs. If you breach this threshold, the platform will respond with a 429 error response code and you will not be able to make new requests for a duration of 5 seconds.
- How many items and options should be sent in one API request?
- In a single request, 1000 items and 1000 options can be sent.
- When does the callback trigger for this API?
- This endpoint processes its tasks asynchronously by utilizing a queueing mechanism. The time it takes to respond to a request you place depends upon the current backlog on the queue, and, the payload size. While we can’t provide any guarantees on the queue, but our infrastructure is equipped to ensure with a 99% probability that you will receive a response within 10 minutes.
- How to configure the "callback_url" for this API?
- POS partners can configure the "callback_url" in the Quint dashboard under Configuration>Webhooks choosing event type as Catalogue publish through API from the dropdown.
- Or, use the Webhooks API to configure the webhook endpoints in Quint Dashboard by specifying the event - inventory_update mentioned in the API documentation.
Note: For more info - https://api-ordering-docs.urbanpiper.com/#catalogue-ingestion-callback
- What is "code" in taxes and charges?
- SGST_P, CGST_P, IGST_P — as "code" constitutes the taxes default to the "percentage" type.
- PC_P, DC_P — as "code" constitutes the charges default to the "percentage" type.
PC_F, DC_F — as "code" constitutes the charges default to the "fixed" type.
- Can "location_ref_ids" inside "taxes" and "charges" used for location-level request?
- No. It is used only in Master-level requests.
- What is the use of "clear_items" and "clear_locations"? When it is used?
- "clear_items": true — this is used for clearing out all the previously grouped items under the given tax/charge slab and consider the one sent in the same request under "item_ref_ids" array.
- "clear_locations": true — this is used for clearing out all the previously grouped locations under the given tax/charge slab and consider the one sent in the same request under "location_ref_ids" array.
- Both these are used only in the Master-level request.
- What should be the tax names?
- The taxes should be sent with a title CGST, SGST. The title of the taxes should have the keyword - CGST, SGST in it depending upon the tax you are sending.
- What should be the "title" of the charges?
- Packaging Charge and Delivery Charge.
- What applicable "value"s are supported for taxes?
- It is expected to pass the split of the taxes in CGST, SGST, and not as GST. Currently, the supported values are - 2.5, 6, 9.
- Is there support for VAT on alcoholic beverages?
- No. Currently, there isn't any support for VAT at the integration level.
- In which request the "taxes" and "charges" data should be included?
- You can include it in the Location level request. If you want to flush the old taxes, you can use them in the Master-level request as well.
- What applicable fields are supported for Taxes and Charges?
- Taxes: By default, the taxes always will be applied on the "item.price" and the type is "percentage" when you pass the CGST_P and SGST_P. All you have to send is the value under "structures.value".
- Charges: Applicable fields are — "item.quantity", "order.order_subtotal" and "item.price").
- Note: If a percentage charge (PC_P/DC_P) needs to be applied on item level, the "applicable_field" supports the value "item.price". If a fixed charge (PC_F/DC_F) needs to be applied on the item level, this field supports the value "item.quantity". If a fixed charge needs to be applied at the order level, this attribute need NOT be specified.
Note: Swiggy will not support charges to be applied on "order.sub_total". Dunzo, Amazon, Talabat, Deliveroo don't support charges configuration as of now through API.
- What are the steps to deactivate the old menu with the complete new menu?
- Refer to point no.5. Adding to that, once the Master-level request is done, make sure it is followed by Location-level requests for associating the items to locations. (Note: No need to send the taxes and charges for Master-level requests.)
- Can the discounts is configurable through API?
- Is it possible to configure the taxes on charges via API?
- No. But from the Quint dashboard, you can configure the taxes on charges for Zomato and Meraki. For other aggregators, it has to be configured at the aggregator's end by contacting merchant PoC.
- Should all the items be included in the "item_ref_ids" array for taxes and charges?
- You need to pass all the valid items that are part of the valid tax slab in the request inside the "item_ref_ids" array.
- How to pass the items which are of 0 tax slab?
- You don't need to group those items under any tax slabs. When no tax slabs are associated with the item, automatically, our system understands it is a zero tax slab items. Also, pass only the valid tax slabs in the request which are associated with at least one item in it. If there are any tax slabs that got no items associated then don't pass those tax slabs in the request. Similarly, for charges as well.
- How nested option groups and nested options are configured via API?
- Nested option Groups and Nested options are configured as Option Groups and options respectively in our system. It is just that based on the mapping in the Catalogue API, it is differentiated as nested. Let us take a below scenario,
Item - Margherita Pizza
Option Groups - Choose your Size
Nested Option Group - Choose Your Toppings (Small Pizza), Choose Your Toppings (Large Pizza)
Options - Small, Large
Nested Options - Tomato (Small Pizza), Cheese(Small Pizza), Tomato (Large Pizza), Cheese (Large Pizza).
You will be passing both the Nested and Non-nested OGs data under the "option_groups" array. But for the Nested OGs array, you won't be passing any items under "item_ref_ids". The Non-nested OG will have items associated with it.
Now, you will be passing both Nested and Non-nested Options under the "options" array. The Option Groups will be associated with the Options using the "opt_grp_ref_ids" array and Nested Option Groups will be associated with the Options again using the "nested_opt_grps" array.
Lastly, the Nested Option Groups will be associated with Nested options inside the "options" array using the "opt_grp_ref_ids" array.