> ## Documentation Index
> Fetch the complete documentation index at: https://docs.fire.rest/llms.txt
> Use this file to discover all available pages before exploring further.

# product.availability_changed

> Fired when a product is activated or deactivated in one or more stores.

`product.availability_changed` is emitted when the availability of one or more products changes — for example, when a restaurant marks a product as out of stock or re-activates it. It controls whether the product appears in the menu and is available for purchase.

Supports multiple products in a single event. When the change affects multiple stores, Fire emits a **single event** with all affected stores listed in `targets`.

## Payload

```json theme={null}
{
  "event": {
    "id": "evt_mno345",
    "type": "product.availability_changed",
    "executionId": "exec_mno123",
    "createdAt": "2025-01-15T14:40:00.000Z",
    "timezone": "America/Guayaquil"
  },
  "data": {
    "account": "1",
    "country": "EC",
    "groupId": "a3f7c2d1-84be-4e10-9b3a-2c5d6e7f8091",
    "targets": [
      {
        "storeId": "b3d2a1f0-6e21-4c3a-9f5d-7a8b9c0d1e2f",
        "storeName": "Laboratorio Brasil",
        "vendorId": "100.6.1350",
        "timezone": "America/Guayaquil",
        "channels": [
          {
            "channelId": "d5f4c3b2-8043-4e5c-9b7f-9c0d1e2f3a4b",
            "channelReferenceName": "iFood"
          }
        ]
      },
      {
        "storeId": "c4e3b2a1-7f32-4d4b-8a6e-8b9c0d1e2f3a",
        "storeName": "Vila Olimpia",
        "vendorId": "100.6.1351",
        "timezone": "America/Guayaquil",
        "channels": [
          {
            "channelId": "d5f4c3b2-8043-4e5c-9b7f-9c0d1e2f3a4b",
            "channelReferenceName": "iFood"
          }
        ]
      }
    ],
    "products": [
      {
        "productId": "e925f6b0-15bf-dc39-2e3f-1a2b284310c6",
        "active": false
      },
      {
        "productId": "prod_size_small",
        "active": true
      }
    ]
  }
}
```

## Fields

### `data`

| Field      | Type      | Description                                                                              |
| ---------- | --------- | ---------------------------------------------------------------------------------------- |
| `account`  | string    | Account identifier — required by downstream systems                                      |
| `country`  | string    | ISO 3166-1 alpha-2 country code (e.g. `EC`, `BR`, `CO`) — required by downstream systems |
| `groupId`  | string    | UUID correlating events from the same publication or sync batch                          |
| `targets`  | object\[] | Stores where the availability change must be applied                                     |
| `products` | object\[] | Products whose availability changed                                                      |

### `data.targets[n]`

Same structure as in [`product.updated`](/en/webhook-reference/product-updated#datatargetsn), without the `listName` field in `channels[n]`.

| Field       | Type      | Description                                                   |
| ----------- | --------- | ------------------------------------------------------------- |
| `storeId`   | string    | Internal store UUID (PK `stores.id`) — not the `store_number` |
| `storeName` | string    | Store operational name                                        |
| `vendorId`  | string    | Store brand identifier                                        |
| `timezone`  | string    | Store IANA timezone (e.g. `America/Guayaquil`)                |
| `channels`  | object\[] | Sales channels where the availability change must be applied  |

### `data.targets[n].channels[n]`

| Field                  | Type   | Description                                                                                 |
| ---------------------- | ------ | ------------------------------------------------------------------------------------------- |
| `channelId`            | string | Internal sales channel UUID (PK `channels.id`) — not the aggregator's external `channel_id` |
| `channelReferenceName` | string | Human-readable name of the sales channel (e.g. `iFood`, `Rappi`)                            |

### `data.products[n]`

| Field       | Type    | Description                               |
| ----------- | ------- | ----------------------------------------- |
| `productId` | string  | Product identifier (UUID)                 |
| `active`    | boolean | `true` to activate, `false` to deactivate |

## Behavior

Setting `active: false` hides the product from the menu and marks it as unavailable for purchase. Setting `active: true` restores it.

This event does not modify any other product data — name, price, images, and modifiers remain unchanged.

Deactivating a product is **not** the same as removing it from the menu: it stays a member, it just stops being available. That's why its menu assignment date (`additionalInfo.assignedAt`) doesn't change with `active: false` and doesn't reset when it goes back to `active: true` — and this event doesn't carry it. It arrives in [`product.updated`](/en/webhook-reference/product-updated#menu-assignment-date) and in [`menu.updated`](/en/webhook-reference/menu-updated-v2).

### `active` is EFFECTIVE availability, not a single switch

`products[n].active` doesn't reflect a single field: it's the result of combining the product's own
visibility with the visibility of **every category** it appears in. A product can live in several
menu categories, and the event is flat per product, so an **OR** is taken across them:

> `active = true` if there is AT LEAST ONE category where (the category is visible AND the product
> is visible in it).

Two consequences worth keeping in mind when processing the event:

* **Hiding an entire category arrives as N product entries**, one for each product whose effective
  availability changed — not as a category change. This event has no way to express categories; menu
  structure travels in [`menu.updated`](/en/webhook-reference/menu-updated-v2)
  (`categories[n].displayInList`).
* **A product that also lives in another visible category does NOT appear in the event**, because its
  effective availability didn't change. That's correct, but it means a product's absence from
  `products[]` doesn't mean its category wasn't touched.

Only products whose effective availability **changed** relative to the previous state are emitted. A
product new to the menu doesn't show up here: it arrives with `menu.updated` / `product.updated`.

## Usage

See [Product publication](/en/guides/product-publication) for the full handling guide.
