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.

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.

FieldDescription
idEvent ID. IDs are time-ordered, so sort: 'id desc' is newest first.
modelModel path. Child collections use parent:child (products:variants); app models use apps//.
typeEvent type, such as order.paid or setting.updated.
dataFor created and deleted, the whole record. For updated, only the changed paths at their new values.
data.idThe record's ID. For settings, the section (checkout, payments) or, for app settings, the app ID.
user_idThe admin user who made the change. Absent for API keys, storefronts, apps, and background tasks.
req_idThe request that produced the event. Matches the request ID in Logs.
date_createdWhen 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
{
  "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 live in the URL query string.

FilterQuery
Modelwhere.model =
Typewhere.type = , or where['data.id'] =
for settings
Userwhere.user_id = , or where.user_id = null for API
Datewhere.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.

To reconstruct one record's history:

Querying events with the API
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 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.

Events API reference

Functions and webhooks

Events in the Help Center