# Events log

Source: https://developers.swell.is/guides/events-log

The **Events** tab at **Developer > Console > Events** is a read-only view of the `events` collection. It lists every create, update, and delete against your store's data as a per-field diff, with the acting user and a link to the originating request in **Logs**.

Nothing changed in the API. Everything the tab shows is available through `GET /events`, and this guide covers both.

## How events are recorded

Swell captures an event after each write to a model with events enabled, which is the default. The `type` is the model's event root plus the operation: `product.updated`, or `product.variant.updated` for a child collection. An `updated` event is written only when data actually changed.

| Field | Description |
| --- | --- |
| id | Event ID. IDs are time-ordered, so sort: 'id desc' is newest first. |
| model | Model path. Child collections use parent:child (products:variants); app models use apps/<app_id>/<name>. |
| type | Event type, such as order.paid or setting.updated. |
| data | For created and deleted, the whole record. For updated, only the changed paths at their new values. |
| data.id | The record's ID. For settings, the section (checkout, payments) or, for app settings, the app ID. |
| user_id | The admin user who made the change. Absent for API keys, storefronts, apps, and background tasks. |
| req_id | The request that produced the event. Matches the request ID in Logs. |
| date_created | When the event was recorded, in UTC. |

Update events store only the changed paths. Arrays keep their full length with unchanged elements as `null`, so an index is the element's real position. Object elements carry their `id`.

**How events are recorded**

**Node**

```json
{
  "id": "68d0a4f1c1b2e3a4d5f60718",
  "model": "products",
  "type": "product.updated",
  "data": {
    "id": "66f1e9a0b3c4d5e6f7a8b9c0",
    "price": 24,
    "tags": [null, null, "clearance"]
  },
  "user_id": "5f3e2d1c0b9a8f7e6d5c4b3a",
  "req_id": "68d0a4f0c1b2e3a4d5f60717",
  "date_created": "2026-09-21T15:02:41.118Z"
}
```

The tab renders this as `price → 24` and `tags[2] → clearance`. Events never store previous values; the tab shows one only when an older event for the same record is already loaded.

The API masks credential-like keys on `settings` events. The tab and its export also mask any path ending in `key`, `secret`, `token`, `password`, `pin`, `pem`, `passphrase`, or `signature`, on every model.

## Filters and search

Filters live in the URL query string.

| Filter | Query |
| --- | --- |
| Model | where.model = <path> |
| Type | where.type = <root.type>, or where['data.id'] = <section> for settings |
| User | where.user_id = <id>, or where.user_id = null for API |
| Date | where.date_created = { $gte, $lte } |

IDs are stored as ObjectIDs, which the API cannot regex-match. A 24-character hex search becomes an exact match on `data.id`, `req_id`, or `id`. Other text is sent as `search`, which matches model and type.

The list loads 50 events at a time, sorted `id desc`, and pages on an `id` cursor. Every filterable field is indexed, so the count is exact when a filter is set. Unfiltered, the API returns its maintained counter, which is approximate and labelled **About**.

## Querying events with the API

To reconstruct one record's history:

**Querying events with the API**

**Node**

```javascript
const { results } = await swell.get('/events', {
  where: { 'data.id': '66f1e9a0b3c4d5e6f7a8b9c0' },
  sort: 'id desc',
  limit: 50,
});
```

Filter on `req_id` for everything one request changed, or on `model`, `type`, `user_id`, and `date_created` for the tab's other views. To page, add `id: { $lt: lastId }` to `where`. Keep `sort: 'id desc'` as a string: events have no default sort, and the cursor depends on it.

## Export

**Export data** under the list exports the matching events as CSV or JSON, paging at 1,000 per request and stopping at 10,000. Rows carry the event ID, date, label, type, model, record ID, user, app, request ID, notes, and changes, with sensitive values masked and changes capped at 50 fields per event.

## Related

Events API reference

Functions and webhooks

Events in the Help Center
