product.updated

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

ChangeExample
The product itselfname, code, description, image, digital menu visibility
Unitadding a unit, renaming a unit, removing a unit
Priceprice list update, branch specific price, bulk price import via Excel
Excludable ingredientadding or removing excludable ingredients in a recipe
Product menuadding or removing sub products, menu content and order
Categorycategory name, image, deleting a category
Taxtax rate change, deleting a tax group
Branch assignmentopening 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

FieldTypeDescription
productIdsarray(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:

Refreshing the menu
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.