# Events

Source: https://developers.swell.is/apps/events

Model events allow you to track and respond to changes in your data. When a record is created, updated, or deleted, Swell checks whether certain conditions are met and generates an event record with metadata about the event. These records can be analyzed using the backend API, and are typically used to constitute activity feeds and to trigger functions or webhooks.

### Standard event types

Swell provides three standard event types for any model: created, updated, and deleted. Each event type includes specific data:

- For `created` events, the entire record is included in the event data.
- For `updated` events, the delta of the changes and the record `id` are included.
- For `deleted` events, the entire deleted record is included in the event data.

These standard events can be enabled or disabled on any model. The event record contains the full object that was changed under the `data` property, along with additional metadata.

### Model-specific event types

Some models have specific event types related to their unique functionality, such as:

- `order.submitted`
- `payment.succeeded`
- `subscription.trial_will_end`

For example, the `payment.succeeded` event fires when a payment record is created or updated with the `success` property. If any functions or webhooks are configured for the event, they will be processed asynchronously.

→ See the [event types reference ](https://developers.swell.is/backend-api/events/event-types)for more details.

Here's an example of an event record created for the `order.paid` event:

```json
{
  "id": "68a7d2f0c1a3b90012f4e8d1",
  "date_created": "2026-08-21T21:59:24.000Z",
  "type": "order.paid",
  "model": "orders",
  "data": {
    "id": "68a7d2e6b7c4a80011d2c3f7",
    "paid": true
  },
  "req_id": "8f4a1b2c3d6e"
}
```

Event records can be retrieved and analyzed using the backend API. For example, using the CLI:

```txt
swell api get "/events?type=order.paid&limit=10"
```

### Custom event types

Apps can define new event types for standard or custom models, extending the range of events you can track and respond to in your application.

### Event hooks

Events occur asynchronously when triggering webhooks, but it's also possible to trigger events synchronously using **event hooks** combined with [app functions](https://developers.swell.is/apps/functions), by using the `before:` or `after:` prefix to an event name. This feature applies to any event listed in this document, however an event can also be configured to work **only** as an event hook, meaning it will not be triggered asynchronously at all.

For example, consider the event `order.paid`. If an app function is tied to this event using a hook, such as `before:order.paid`, then the function will be called with the order payload before the event is concluded. This allows the function to modify the record before being saved, or to return an error, entirely preventing the change from occurring.

A `before:` hook can reject the operation entirely by returning `req.reject(code, message, { status })`. The write is blocked, and the API caller receives a structured error response containing the code, message, and status. The status must be in the 400–499 range, otherwise it defaults to `422`.

`functions/require-order-approval.js`

```javascript
export const config = {
  description: 'Require approval for large orders',
  model: {
    events: ['before:order.paid'],
  },
};

export default async function (req) {
  if (req.data.grand_total > 10000) {
    return req.reject(
      'manual_approval_required',
      'Orders over $10,000 require manual approval',
      { status: 422 },
    );
  }
}
```

### Event conditions

You can define and specify when an event should be triggered based on specific criteria using `conditions`. They are formatted similarly to API query filters used for record retrieval. Event conditions support a range of operators, including Swell-specific operators like `$record`, `$data`, and `$method`, as well as common MongoDB query operators such `$eq`, `$ne`, `$gt` and more. These operators provide a flexible way to define conditions based on various aspects of your data and its changes. A `conditions` criteria can also leverage a `$formula` property to evaluate data using Swell’s formula syntax.

Conditions are evaluated against the record with the pending changes applied. Within conditions, `$record` refers to the previous record values, `$data` refers to the incoming change only, and `$method` matches the API method (`post`, `put`, or `delete`).

For example, this event fires only when a product's stock level drops below 10, from a previous value of 10 or more:

```json
{
  "id": "stock_low",
  "conditions": {
    "stock_level": { "$lt": 10 },
    "$record": { "stock_level": { "$gte": 10 } },
    "$data": { "stock_level": { "$exists": true } }
  }
}
```

For more advanced logic, a `$formula` condition evaluates an expression against the record using Swell's formula syntax:

```json
{
  "id": "large_order",
  "conditions": {
    "$formula": "grand_total >= 1000"
  }
}
```

→ See the [data model reference](https://developers.swell.is/backend-api/data-models/the-data-model) `events` object for the complete schema used to define custom events on data models.

## Examples

You can configure events on a model to trigger custom logic or integrations when specific actions occur, such as creating, updating, or deleting a record. These [events](https://developers.swell.is/backend-api/events) can be subscribed to by webhooks and functions.

To define events on a model, you can add an `events` property in the model configuration file. Here's a simple example of defining events on the "things" model:

`models/things.json`

```json
{
  "collection": "things",
  "label": "Things",
  "fields": {
    "name": {
      "type": "string",
      "required": true
    },
    "description": {
      "type": "string"
    },
    "status": {
      "type": "string",
      "enum": ["active", "inactive"]
    }
  },
  "events": {
    "enabled": true,
    "types": [
      { "id": "created" },
      { "id": "updated" },
      { "id": "deleted" },
      {
        "id": "activated",
        "conditions": {
          "status": "active",
          "$record": {
            "status": { "$ne": "active" }
          }
        }
      }
    ]
  }
}
```

In this example, we've defined three standard events: `created`, `updated`, and `deleted`. These events are triggered by the corresponding actions on the "things" model. Note that it's also possible to add conditions to these standard events.

Also in this example, we've added a new field called `status` to the "things" model with two possible values: `active` and `inactive`, and defined a custom event called `activated`, which is triggered when a Thing changes its status from `inactive` to `active`.
