> ## 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.

# store.updated

> A store's configuration was published to its channels — the whole store, its channels with resolved schedules, and the publication that produced the event.

> [!NOTE]
>
> **Limited availability.** This event is being rolled out and is enabled per account. Ask your Fire contact whether it already applies to yours.

> [!WARNING]
>
> This is the **Integration Flows** `store.updated` event, documented on this page. It is **not** the aggregator-integration webhook with the same name described in [Webhook reference → `store.updated`](https://docs.fire.rest/en/webhook-reference/store-updated): that one belongs to a different system, has a different shape, and does not change.

`store.updated` fires every time a store's configuration is **published** to its channels: first publication, publishing a draft, re-synchronizing, switching a channel on or off, applying an override, archiving. It always carries the **whole store** — never a diff. Treat it as a full replacement of what you know about that store.

Like `store.business_day_closed`, it is a **store-level** event: one per publication, not one per order or per channel. A publication that touches several channels produces a single event with every channel inside, and each flow that receives it gets that event once, with the whole store.

## Trigger condition

Each publication of a store emits **one** `store.updated`. `data.publication.reason` tells you what produced it:

| `reason` | What happened |
| - | - |
| `publish` | The store was published for the first time (also when a store is created already published). |
| `draft` | The pending changes of a published store were applied. Channels being switched off travel with `enabled: false`. |
| `resync` | Someone re-synchronized the store; it travels exactly as it is. |
| `channel_toggle` | A channel was switched on or off for the store, by hand or by its schedule. |
| `override_apply` / `override_revert` | An override was applied to the store, or reverted. |
| `archive` | The store was archived — see [Archiving](#archiving). |

New `reason` values (the contract already allows `retry`) and new `mode` values may appear. Treat a value you do not know as a normal publication: the event still carries the whole store.

A publication can also be **scheduled**: nothing is emitted when it is scheduled; the event fires when the scheduled time arrives, with `publication.mode: "scheduled"` and `publication.scheduledAt`. Cancelling a scheduled publication emits nothing.

**Nothing is emitted** when changes are saved without publishing them to the channels, or when the business day opens or closes.

| | |
| - | - |
| Coverage | Every country, on accounts where the event is enabled |
| Publication id | `data.publication.id` — the same in every delivery and in every flow that receives that publication |
| Delivery id | `event.id`, as in every event (the flow execution) |
| Order | `data.publication.sequence`, per store — see [The latest publication wins](#the-latest-publication-wins) |
| Entity | `_meta.triggerEntityId` is the store UUID (`data.store.uid`) |

> [!NOTE]
>
> A flow limited to certain channels receives a publication when it touches **at least one** of them — and it receives the **whole** event, every channel included. Pick the channels that are yours from `data.channels`.

## Example — real payload (sanitized and shortened)

```json theme={null}
{
  "event": {
    "id": "5b0f3c9e-2d71-4a8e-9f14-6c3e2a7d8b10",
    "type": "store.updated",
    "emittedAt": "2026-10-27T02:40:46.985Z",
    "createdAt": "2026-10-27T02:40:47.402Z"
  },
  "data": {
    "store": {
      "uid": "a4019cad-bbac-4269-9f8d-f29654e92c45",
      "code": "BR-SP-001",
      "name": "Loja Centro - SP",
      "number": 2,
      "status": "PUBLISHED",
      "active": true,
      "phone": "+5511999990000",
      "email": "loja.centro@example.com",
      "address": "Av. Exemplo 1000, Centro, São Paulo - SP",
      "externalId": "200400500",
      "vendor": { "uid": "100.2.1", "name": "Sandbox Brand", "description": null, "loyaltyPlan": false },
      "account": { "uid": "100", "name": "Sandbox", "description": null },
      "locationInfo": {
        "city":     { "uid": "1", "code": "SAO", "name": "São Paulo" },
        "country":  { "uid": "6", "code": "BR",  "name": "Brasil", "phoneCode": "+55" },
        "location": { "lat": "-23.5632", "lon": "-46.6543" },
        "timezone": "America/Sao_Paulo",
        "currencyCode": "BRL"
      },
      "storeFiscalConfig": {
        "enabled": true,
        "company": { "govIdType": "CNPJ", "govIdNumber": "00000000000000", "legalName": "Sandbox LTDA", "tradeName": "Sandbox" },
        "govIdType": "CNPJ",
        "govIdNumber": "00000000000000",
        "secondaryGovIdType": "INSCRICAO_ESTADUAL",
        "secondaryGovIdNumber": "000000000000",
        "metadata": { "neverstop": { "url": "", "enabled": false }, "storeCode3S": "50000001", "serialNumber": 1 }
      },
      "metadata": {
        "taxesInfo": { "taxRate": 4, "vatRatePercentage": 4 },
        "deliveryInfo": { "cookTime": 15, "minimumOrder": 1, "shippingCost": 1 }
      }
    },
    "channels": [
      {
        "code": "KIOSK",
        "enabled": true,
        "published": true,
        "fulfillmentTypes": [
          {
            "code": "DINE_IN",
            "enabled": true,
            "schedules": [
              { "day": "MONDAY",    "startTime": "09:00", "endTime": "22:30" },
              { "day": "TUESDAY",   "startTime": "09:00", "endTime": "22:30" },
              { "day": "WEDNESDAY", "startTime": "09:00", "endTime": "22:30" },
              { "day": "THURSDAY",  "startTime": "09:00", "endTime": "22:30" },
              { "day": "FRIDAY",    "startTime": "09:00", "endTime": "22:30" },
              { "day": "SATURDAY",  "startTime": "09:00", "endTime": "22:30" },
              { "day": "SUNDAY",    "startTime": "09:00", "endTime": "22:30" }
            ]
          },
          {
            "code": "TAKEAWAY",
            "enabled": true,
            "schedules": [ /* same 7 days */ ]
          }
        ]
      },
      {
        "code": "POS",
        "enabled": true,
        "published": true,
        "fulfillmentTypes": [
          { "code": "DINE_IN",  "enabled": true, "schedules": [ /* same 7 days */ ] },
          { "code": "TAKEAWAY", "enabled": true, "schedules": [ /* same 7 days */ ] }
        ]
      },
      {
        "code": "IFOOD",
        "enabled": false,
        "published": false,
        "fulfillmentTypes": [
          { "code": "DELIVERY", "enabled": false, "schedules": [ /* same 7 days */ ] }
        ]
      }
    ],
    "operationSchedule": [
      { "day": "MONDAY",    "startTime": "07:00", "endTime": "23:00" },
      { "day": "TUESDAY",   "startTime": "07:00", "endTime": "23:00" },
      { "day": "WEDNESDAY", "startTime": "07:00", "endTime": "23:00" },
      { "day": "THURSDAY",  "startTime": "07:00", "endTime": "23:00" },
      { "day": "FRIDAY",    "startTime": "07:00", "endTime": "23:00" },
      { "day": "SATURDAY",  "startTime": "07:00", "endTime": "23:00" },
      { "day": "SUNDAY",    "startTime": "07:00", "endTime": "23:00" }
    ],
    "salesSchedule": [
      { "day": "MONDAY",    "startTime": "09:00", "endTime": "22:30" },
      { "day": "TUESDAY",   "startTime": "09:00", "endTime": "22:30" },
      { "day": "WEDNESDAY", "startTime": "09:00", "endTime": "22:30" },
      { "day": "THURSDAY",  "startTime": "09:00", "endTime": "22:30" },
      { "day": "FRIDAY",    "startTime": "09:00", "endTime": "22:30" },
      { "day": "SATURDAY",  "startTime": "09:00", "endTime": "22:30" },
      { "day": "SUNDAY",    "startTime": "09:00", "endTime": "22:30" }
    ],
    "publication": {
      "id": "0fc14118-15e2-4964-8ae6-970dd801b836",
      "sequence": 2,
      "mode": "now",
      "reason": "resync",
      "channels": ["KIOSK", "POS"],
      "scheduledAt": null,
      "requestedBy": { "id": "7b1e4c2a-0d3f-4a5b-8c6d-9e0f1a2b3c4d", "name": "Ana Souza" }
    }
  },
  "_meta": {
    "executionId": "5b0f3c9e-2d71-4a8e-9f14-6c3e2a7d8b10",
    "flowId": "9a2b3c4d-7e8f-4a1b-9c2d-3e4f5a6b7c8d",
    "flowName": "Store sync",
    "attempt": "1",
    "triggerEntityId": "a4019cad-bbac-4269-9f8d-f29654e92c45"
  }
}
```

## `data.*` reference

### `data.store`

**store** `object`

The **same V4 store block** that travels on order events — `uid`, `code`, `name`, `phone`, `email`, `address`, `externalId`, `vendor`, `account`, `locationInfo` (with `country.phoneCode`), `metadata` and `storeFiscalConfig` (may be `null`). Field reference in [`order.completed` → `data.store`](https://docs.fire.rest/en/events/order-completed#data-store). `phone` comes in international format (`+` and digits, e.g. `+5511999990000`). It may carry a number that is not real (for example, all zeros) if the store has no phone set, or the value exactly as stored if the country has no calling code. `metadata` is the store's **free key-value** configuration: Fire does not impose its keys, some integrations read well-known ones (in the example, `taxesInfo` and `deliveryInfo`), and it is `{}` when the store has none. On top of that block, this event adds:

**fields added by store.updated**

**number** `integer | null`

The store's sequential number in Fire. `null` when it is not known.

**status** `string`

Publication state of the store: `DRAFT`, `PUBLISHED`, `PARTIALLY_PUBLISHED` or `ARCHIVED`.

**active** `boolean`

Whether the store is active. Always `false` when archived.

### `data.channels`

**channels** `array`

**Every** channel configured for the store — not only the ones this publication is about (those are in `publication.channels`). A channel or fulfillment type that is switched off still travels, with `enabled: false`: that is how you learn it was taken down.

**channels\[]**

**code** `string`

Channel code, written as configured in Fire (`KIOSK`, `POS`, `iFood`, `99`, …). Compare without assuming a particular case.

**enabled** `boolean`

Whether the channel is enabled for the store.

**published** `boolean`

Whether the channel is among the store's published channels.

**fulfillmentTypes** `array`

The channel's fulfillment types.

**fulfillmentTypes\[]**

**code** `string`

Fulfillment type code (`DELIVERY`, `TAKEAWAY`, `DINE_IN`, …).

**enabled** `boolean`

Whether the fulfillment type is enabled on this channel.

**schedules** `array`

The **effective** schedule, already resolved: the fulfillment type's own schedule; if it has none, the channel's; if the channel has none either, the store's `salesSchedule`. Each entry is `{ day, startTime, endTime }`, same shape as below. You do not need to apply the inheritance yourself.

### `data.operationSchedule` and `data.salesSchedule`

**operationSchedule** `array`

The store's operating hours. Each entry: `day` (`MONDAY` … `SUNDAY`), `startTime` and `endTime` (`HH:mm`).

**salesSchedule** `array`

The store's sales hours, same shape. It is the fallback for channels and fulfillment types without a schedule of their own — already applied in `channels[].fulfillmentTypes[].schedules`.

### `data.publication`

**publication** `object`

The publication that produced this event.

**publication**

**id** `string`

UUID of the publication. The same in every delivery and in every flow that receives it — use it to recognize a publication you already applied.

**sequence** `integer`

Per-store counter: it goes up by one with each emitted publication of that store. The higher one is the newer one. See [The latest publication wins](#the-latest-publication-wins).

**mode** `string`

`now` (published on the spot) or `scheduled` (fired by a schedule). New values may appear; treat them as a normal publication.

**reason** `string`

What produced the publication: `publish`, `draft`, `resync`, `channel_toggle`, `override_apply`, `override_revert` or `archive`. New values may appear (e.g. `retry`); treat them as a normal publication. See [Trigger condition](#trigger-condition).

**channels** `string[]`

The channel codes this publication is about: the ones chosen when publishing, every enabled channel on a re-sync, the channel switched on or off in a `channel_toggle`, the single channel of a one-channel re-sync, every enabled channel on an `override_apply` or `override_revert`, and on archiving, the published channels plus the enabled ones.

**scheduledAt** `string | null`

ISO 8601 UTC time the publication was scheduled for. `null` when `mode` is `now`.

**requestedBy** `object`

`{ id, name }` — who requested it. Either can be `null`; automatic runs may arrive with `id: null` and `name: "CRON"`.

## The latest publication wins

Every event carries the **whole** store, so the most recent publication replaces everything before it. Fire already takes care of the order for you:

* Within a flow, the publications of **one store** are delivered one at a time, in the order they were emitted. Different stores move in parallel.
* When a store gets a new publication that covers the same channels, deliveries of older publications that were still waiting are cancelled; the others still go out, in order.

`publication.sequence` is still useful data: you can store the last one you applied per store, and recognize a stale payload if one ever reaches you — for example, a manual replay of an old delivery, which keeps its original `sequence`.

## Archiving

Archiving a store emits a `store.updated` with `publication.reason: "archive"`. It carries the archived store: `store.status: "ARCHIVED"`, `store.active: false`, and **every** channel and fulfillment type with `enabled: false` (and channels with `published: false`). To handle archiving separately, branch on `reason` or on `status`.

> [!NOTE]
>
> Integration Flows do not emit a separate `store.deleted` event: archiving is a `store.updated`.

## Handler example

```js theme={null}
async function onStoreUpdated(data) {
  const { store, channels, publication } = data;

  // 1. Already applied this publication? (same id on every delivery)
  if (await db.storePublications.exists(publication.id)) return;

  // 2. Optional: keep the sequence to recognize a stale payload
  const last = await db.stores.lastSequence(store.uid);
  if (last != null && publication.sequence < last) return;

  // 3. Full replacement — the event carries the whole store
  const mine = channels.filter((c) => MY_CHANNELS.includes(c.code.toUpperCase()));
  await db.stores.replace(store.uid, {
    code: store.code,
    name: store.name,
    active: store.active,
    archived: store.status === "ARCHIVED",
    metadata: store.metadata,
    channels: mine,
    sequence: publication.sequence,
  });
  await db.storePublications.add(publication.id);
}
```

## Common pitfalls

* **It is not a diff.** A channel missing from your copy is not "unchanged" — the event lists every channel. Replace, do not merge.
* **A switched-off channel still travels.** Read `enabled`; do not assume that a channel present in the event is open.
* **`publication.channels` is not the list of channels.** It says what this publication was about; the store's channels are in `data.channels`.
* **Do not dedupe by `event.id`.** It identifies the delivery; the publication is `data.publication.id`.
* **Channel codes keep the case they were configured with** (`iFood`, `KIOSK`). Normalize before comparing.

## Related events

> **[store.business\_day\_closed](https://docs.fire.rest/en/events/store-day-closed.md)**
>
> The other store-level event: a store closed its business day.

> **[order.completed](https://docs.fire.rest/en/events/order-completed.md)**
>
> Field reference for the V4 `store` block shared with this event.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.