product.updated
This event is triggered when a field visible in the Product List (/Products) response changes.
Its purpose is to let you refresh the menu only when something actually changed, instead of polling on a fixed schedule.
Events should be processed in batches, not one by one. Recommended flow: buffer incoming events for about 3 minutes, then call /Products once and update your menu. /Products can already be called every 3 minutes; this rhythm keeps you within the rate limit and turns a burst of events into a single request.
What triggers it
| Change | Example |
|---|---|
| The product itself | name, code, description, image, digital menu visibility |
| Unit | adding a unit, renaming a unit, removing a unit |
| Price | price list update, branch specific price, bulk price import via Excel |
| Excludable ingredient | adding or removing excludable ingredients in a recipe |
| Product menu | adding or removing sub products, menu content and order |
| Category | category name, image, deleting a category |
| Tax | tax rate change, deleting a tax group |
| Branch assignment | opening or closing a product in a branch |
Deletions are reported with this event as well; there is no separate product.deleted event. A deleted product is no longer returned in the /Products response.
It does not matter whether the change was made from the head office application (HQ) or from the branch's own Adisyo application; the event is sent in both cases.
The event only tells you which products were affected, not what changed. The change may not produce a visible difference in the response; handling the event idempotently is enough.
Payload Structure
The payload carries only the identifiers of the affected products. You read the current data from the /Products endpoint.
Because a single operation can affect multiple products (a category rename, deleting a tax group, a bulk Excel import), products are listed in the productIds array. When a single product changes the array simply has one element.
{
"eventId": "7a2b5c91-3e64-4d08-b1f7-9c02ad4e6b53",
"webhookEventType": "product.updated",
"eventTimeUtc": "2025-10-21T11:59:50.1855135Z",
"data": {
"productIds": [2230902, 2230903, 2230904]
},
"restaurantIdentity": "3edc2d46-bfc0-44d1-b701-f18e56306aed"
}Data Fields
| Field | Type | Description |
|---|---|---|
productIds | array(number) | IDs of the affected products. Same as productId in the /Products response |
restaurantIdentity identifies the branch where the change happened; the event is always branch scoped. If a change made from head office affects multiple branches, a separate event is sent for each branch, and each branch receives an event containing only the products visible in that branch.
Indirectly affected products
A change can also affect products that were not touched directly. In that case all affected products are listed in the same event:
- When the unit of an ingredient is deleted, the parent products using that ingredient in their recipe are also reported.
- When a product is deleted, the products that contain it as a sub product in their menu are also reported.
- When a tax group is deleted, all products in that group are moved to the default group and all of them are reported.
Usage Example
Buffer the events as they arrive; when the window closes, refresh the menu with a single request:
curl -X GET "https://ext.adisyo.com/api/External/v2/Products" \
--header "x-api-key: <api-key-provided-by-adisyo>" \
--header "x-api-secret: <secret-for-the-restaurant-being-requested>" \
--header "x-api-consumer: <a-text-identifying-the-requesting-company>"You may use productIds to decide which products need reprocessing on your side, but the data is always read from the /Products response.