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

# Automation Queries

> The query library for scheduled automations: what each query targets and the arguments that tune it.

A scheduled [automation](/concepts/automation/reactions) runs a query on a schedule to select a set of profiles (or records), then runs its actions on each match. The query is chosen with the automation's `query` field and tuned with its `arguments`. This page lists the available queries and what every argument does.

## How an automation is set up

| Field         | Meaning                                                                                                    |
| ------------- | ---------------------------------------------------------------------------------------------------------- |
| `name`        | A label for the automation.                                                                                |
| `query`       | Which rule to run, the query name, for example `dailySpend` (see the reference below).                     |
| `arguments`   | Settings that tune the query (see [Argument format](#argument-format)).                                    |
| `type`        | `scheduled` for a recurring automation, or `date` for a one-off on a specific day.                         |
| `slot`        | For `scheduled`: the time of day it runs, as a slot handle, for example `AU-MEL-7` (07:00 Melbourne time). |
| `date`        | For `date`: the day it should run (`YYYY-MM-DD`).                                                          |
| `frequency`   | How often a scheduled automation runs: `daily` (default), `weekly`, `fortnightly`, or `monthly`.           |
| `run_at`      | Pairs with `frequency`: day of the month (monthly) or day of the week (weekly/fortnightly).                |
| `taskable`    | How matches are processed (see [Processing mode](#processing-mode-taskable)).                              |
| `is_active`   | Only active automations run.                                                                               |
| `description` | Optional free text.                                                                                        |
| `actions`     | What to do for each match. See [Reactions overview](/dev-guides/reactions/overview).                       |

## Processing mode (taskable)

By default (`taskable` is `false`) an automation processes every match in a single run, dispatching the actions as it goes.

Set `taskable` to `true` to instead queue each match and process it individually in the background. This mode suits large audiences and is safe to re-run: if the same run happens again, or a missed run is caught up later, the same profile is not processed twice for that run. Use it when an automation may match a very large number of profiles, or where reliable, no-duplicate processing matters.

## Argument format

Each query is tuned with a set of named arguments. The examples below use a shorthand of `name: value`, for example:

```json theme={null}
{
  "min_spend": 100,
  "max_spend": 500
}
```

Only the arguments listed for a query have any effect. Time-based automations always work relative to the day they run.

## What the action receives

For most automations the action runs against the matched profile. Some queries also pass extra data the action can use:

* **Spend totals** (`dailySpendTotalByItem`, `dailySpendTotalByItemProduct`) pass the calculated spend value, so you can give a reward proportional to spend.
* **Returns** (`dailyReturnAmountByItem`) pass the calculated return value.
* **Stock changes** (`lastStockChangeList`) pass the products that changed.
* **List items** (`unpurchasedListItems`) pass the items not yet bought.
* **Connected birthday** (`upcomingConnectedBirthMonth`) runs against the profile's linked primary account (for example a parent for a dependant).
* **Expired reservations** (`expiredReservations`) run against the reservation itself, including its profile and item.

## Query reference

Each entry gives the query name (the value for the `query` field), what it targets, an argument table, any behaviour worth noting, and an example. In filter arguments, set `type` to `include` or `exclude` (for `discount_reason_filter`, `allow` or `block`).

### Spend and transactions

#### `dailySpend`

Targets profiles whose total spend yesterday reached `min_spend` (and, optionally, no more than `max_spend`). The classic "spend \$X, get a reward" automation.

| Argument          | Required | Type         | Default             | What it does                                                                          |
| ----------------- | -------- | ------------ | ------------------- | ------------------------------------------------------------------------------------- |
| `min_spend`       | Yes      | number       | none                | Minimum total spend yesterday.                                                        |
| `max_spend`       | No       | number       | none                | Optional upper limit on yesterday's spend.                                            |
| `delay`           | No       | number       | 3                   | Grace window (days) so transactions recorded a little late are still counted.         |
| `timezone`        | No       | text         | Australia/Melbourne | Sets what counts as "yesterday" for the automation.                                   |
| `location_filter` | No       | object       | none                | Only (or never) count transactions at the given location IDs. Shape: `{ type, ids }`. |
| `date`            | No       | `YYYY-MM-DD` | none                | Only run on this exact date; leave blank for normal recurring runs.                   |

A profile that already received a spend reward that day is not matched again.

```json theme={null}
{
  "min_spend": 100,
  "max_spend": 500,
  "timezone": "Australia/Melbourne"
}
```

#### `dailySpendByItem`

Like `dailySpend`, but spend is counted from the individual items bought, so you can target spend on particular products, SKUs, or discount conditions.

| Argument                 | Required | Type         | Default             | What it does                                                                                                                                                                  |
| ------------------------ | -------- | ------------ | ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `min_spend`              | Yes      | number       | none                | Minimum item spend yesterday.                                                                                                                                                 |
| `max_spend`              | No       | number       | none                | Optional upper limit.                                                                                                                                                         |
| `delay`                  | No       | number       | 3                   | Grace window (days) for late-recorded transactions.                                                                                                                           |
| `timezone`               | No       | text         | Australia/Melbourne | Sets what counts as "yesterday".                                                                                                                                              |
| `location_filter`        | No       | object       | none                | Only (or never) count transactions at the given location IDs. Shape: `{ type, ids }`.                                                                                         |
| `sku_filter`             | No       | object       | none                | Only (or never) count the given product SKUs. Shape: `{ type, values }`.                                                                                                      |
| `discount_filter`        | No       | object       | none                | Limit to discounted or full-price products. Shape: `{ type }`, where `include` is discounted only and `exclude` is full-price only.                                           |
| `discount_reason_filter` | No       | object       | none                | Filter by discount reason. Shape: `{ type, keyword }`, where `allow` counts an item only if every discount reason mentions the keyword and `block` skips an item if any does. |
| `exclude_discount`       | No       | true/false   | none                | Ignore items that were discounted at the register.                                                                                                                            |
| `date`                   | No       | `YYYY-MM-DD` | none                | Only run on this exact date; leave blank for normal recurring runs.                                                                                                           |

A profile that already received a spend reward that day is not matched again.

```json theme={null}
{
  "min_spend": 50,
  "sku_filter": {
    "type": "include",
    "values": ["SKU-1", "SKU-2"]
  }
}
```

#### `dailySpendTotalByItem`

Same targeting as `dailySpendByItem`, and it also calculates each profile's exact qualifying spend and passes it to the action, for rewards proportional to spend.

| Argument                 | Required | Type                  | Default             | What it does                                                                                                  |
| ------------------------ | -------- | --------------------- | ------------------- | ------------------------------------------------------------------------------------------------------------- |
| `min_spend`              | Yes      | number                | none                | Minimum item spend.                                                                                           |
| `convert_rate`           | No       | number                | 1                   | Multiplier applied to the calculated spend before it is passed to the action (for example dollars to points). |
| `exclude_return`         | No       | true/false            | none                | Ignore returned items when totalling.                                                                         |
| `delay`                  | No       | number                | 3                   | Grace window (days) for late-recorded transactions.                                                           |
| `timezone`               | No       | text                  | Australia/Melbourne | Sets what counts as "yesterday".                                                                              |
| `location_filter`        | No       | object                | none                | Only (or never) count transactions at the given location IDs. Shape: `{ type, ids }`.                         |
| `sku_filter`             | No       | object                | none                | Only (or never) count the given product SKUs. Shape: `{ type, values }`.                                      |
| `discount_filter`        | No       | object                | none                | Limit to discounted or full-price products. Shape: `{ type }`.                                                |
| `discount_reason_filter` | No       | object                | none                | Filter by discount reason. Shape: `{ type, keyword }`, `allow` or `block` as above.                           |
| `exclude_discount`       | No       | true/false            | none                | Ignore items discounted at the register.                                                                      |
| `staff_discount_filter`  | No       | text                  | none                | Ignore items whose discount mentions this keyword (for example a staff discount).                             |
| `date`                   | No       | `YYYY-MM-DD`          | none                | Only run on this exact date.                                                                                  |
| `start_date`             | No       | `YYYY-MM-DD HH:MM:SS` | none                | Only count transactions on or after this point (for totals running from a launch date).                       |

<Note>
  Unlike the other spend automations, this one does not prevent matching a profile twice in the same day. Use a `date` setting or idempotent actions if same-day re-runs are possible.
</Note>

```json theme={null}
{
  "min_spend": 100,
  "convert_rate": 0.1,
  "exclude_return": true
}
```

#### `dailySpendTotalByItemProduct`

The most filterable spend automation: everything `dailySpendTotalByItem` does, plus product-tag targeting and a configurable per-day reward cap.

| Argument                 | Required | Type                  | Default             | What it does                                                                          |
| ------------------------ | -------- | --------------------- | ------------------- | ------------------------------------------------------------------------------------- |
| `min_spend`              | Yes      | number                | none                | Minimum item spend.                                                                   |
| `convert_rate`           | No       | number                | 1                   | Multiplier applied to the calculated spend before it is passed to the action.         |
| `exclude_return`         | No       | true/false            | none                | Ignore returned items.                                                                |
| `max_reward_issued`      | No       | number (min 1)        | 1                   | Skip a profile only once they have already received this many spend rewards today.    |
| `product_tags_filter`    | No       | object                | none                | Only (or never) count products with the given tag IDs. Shape: `{ type, ids }`.        |
| `delay`                  | No       | number                | 3                   | Grace window (days) for late-recorded transactions.                                   |
| `timezone`               | No       | text                  | Australia/Melbourne | Sets what counts as "yesterday".                                                      |
| `location_filter`        | No       | object                | none                | Only (or never) count transactions at the given location IDs. Shape: `{ type, ids }`. |
| `sku_filter`             | No       | object                | none                | Only (or never) count the given product SKUs. Shape: `{ type, values }`.              |
| `discount_filter`        | No       | object                | none                | Limit to discounted or full-price products. Shape: `{ type }`.                        |
| `discount_reason_filter` | No       | object                | none                | Filter by discount reason. Shape: `{ type, keyword }`, `allow` or `block` as above.   |
| `exclude_discount`       | No       | true/false            | none                | Ignore items discounted at the register.                                              |
| `staff_discount_filter`  | No       | text                  | none                | Ignore items whose discount mentions this keyword.                                    |
| `date`                   | No       | `YYYY-MM-DD`          | none                | Only run on this exact date.                                                          |
| `start_date`             | No       | `YYYY-MM-DD HH:MM:SS` | none                | Only count transactions on or after this point.                                       |

```json theme={null}
{
  "min_spend": 80,
  "product_tags_filter": {
    "type": "include",
    "ids": [10, 11]
  },
  "max_reward_issued": 2
}
```

#### `bigShop`

Targets profiles who spent over `min_spend` on a single day, a "big basket" trigger. Profiles who changed tier around that time are excluded, so it does not fire just because someone was upgraded.

| Argument    | Required | Type   | Default | What it does                                       |
| ----------- | -------- | ------ | ------- | -------------------------------------------------- |
| `min_spend` | Yes      | number | none    | Minimum spend on the day evaluated.                |
| `delay`     | No       | number | 3       | Which recent day to evaluate (how many days back). |

```json theme={null}
{
  "min_spend": 300,
  "delay": 3
}
```

#### `firstShop`

Targets profiles who made their first transaction yesterday, for welcome and first-transaction journeys.

| Argument    | Required | Type           | Default | What it does                                              |
| ----------- | -------- | -------------- | ------- | --------------------------------------------------------- |
| `max_spend` | No       | number         | none    | Optional cap on the first transaction total.              |
| `channel`   | No       | `web` or `pos` | none    | Only count a first transaction made through this channel. |

```json theme={null}
{
  "channel": "pos",
  "max_spend": 200
}
```

### Returns

#### `dailyReturnAmountByItem`

Targets profiles who returned at least `min_return` worth of items yesterday. The calculated return value is passed to the action.

| Argument                    | Required | Type                  | Default             | What it does                                                                         |
| --------------------------- | -------- | --------------------- | ------------------- | ------------------------------------------------------------------------------------ |
| `min_return`                | Yes      | number                | none                | Minimum returned value.                                                              |
| `convert_rate`              | No       | number                | 1                   | Multiplier applied to the calculated return value before it is passed to the action. |
| `reward_definition_type`    | No       | text                  | none                | Only profiles who were issued a reward of this type today.                           |
| `reward_definition_handle`  | No       | text                  | none                | Or of this specific reward definition (takes priority over type).                    |
| `achievement_definition_id` | No       | number                | none                | If set, the profile's achievement progress is passed to the action.                  |
| `delay`                     | No       | number                | 3                   | Grace window (days) for late-recorded returns.                                       |
| `timezone`                  | No       | text                  | Australia/Melbourne | Sets what counts as "yesterday".                                                     |
| `location_filter`           | No       | object                | none                | Only (or never) count returns at the given location IDs. Shape: `{ type, ids }`.     |
| `sku_filter`                | No       | object                | none                | Only (or never) count the given product SKUs. Shape: `{ type, values }`.             |
| `date`                      | No       | `YYYY-MM-DD`          | none                | Only run on this exact date.                                                         |
| `start_date`                | No       | `YYYY-MM-DD HH:MM:SS` | none                | Only count returns on or after this point.                                           |

The return value passed to the action is negative (returns reduce value).

```json theme={null}
{
  "min_return": 50,
  "reward_definition_type": "spend"
}
```

### Lifecycle and recency

#### `lapsed`

Targets profiles whose last transaction was exactly N days ago, for win-back at a fixed point.

| Argument | Required | Type               | Default | What it does                                     |
| -------- | -------- | ------------------ | ------- | ------------------------------------------------ |
| `days`   | Yes      | number             | none    | Exact number of days since the last transaction. |
| `tier`   | No       | text (tier handle) | none    | Limit to a tier.                                 |

This is an exact match, not "N days or more", so choose the single day to fire on.

```json theme={null}
{
  "days": 30,
  "tier": "gold"
}
```

#### `inactiveProfiles`

Targets long-inactive profiles, based on how long ago they joined and (optionally) how long since their last transaction, with extra filters.

| Argument          | Required | Type                    | Default             | What it does                                                                                             |
| ----------------- | -------- | ----------------------- | ------------------- | -------------------------------------------------------------------------------------------------------- |
| `join_unit`       | Yes      | days/weeks/months/years | none                | Unit for "joined at least ago".                                                                          |
| `join_value`      | Yes      | number                  | none                | Quantity for `join_unit`.                                                                                |
| `last_shop_unit`  | No       | days/weeks/months/years | none                | If set, require the last transaction to be older than this. If left out, require no transactions at all. |
| `last_shop_value` | No       | number                  | none                | Quantity for `last_shop_unit`.                                                                           |
| `comms_operator`  | No       | `and` or `or`           | none                | How to combine `comms_filter` conditions.                                                                |
| `comms_filter`    | No       | object                  | none                | Match on the profile's communication preferences.                                                        |
| `status_filter`   | No       | object                  | none                | Only (or never) include profiles with the given status handles. Shape: `{ type, handles }`.              |
| `timezone`        | No       | text                    | Australia/Melbourne | Sets the day boundary for the windows.                                                                   |

```json theme={null}
{
  "join_unit": "months",
  "join_value": 6,
  "last_shop_unit": "months",
  "last_shop_value": 3
}
```

#### `joinDate`

Targets profiles who joined exactly a set time ago, for timed onboarding messages. Supports an hourly option as well as days/weeks/months/years.

| Argument         | Required | Type                          | Default             | What it does                                        |
| ---------------- | -------- | ----------------------------- | ------------------- | --------------------------------------------------- |
| `unit`           | Yes      | hours/days/weeks/months/years | none                | Window unit.                                        |
| `value`          | Yes      | number                        | none                | Quantity for `unit`.                                |
| `delay_hour`     | No       | number                        | none                | Extra hour offset (only used with `unit` of hours). |
| `no_transaction` | No       | true/false                    | none                | Only profiles who have never transacted.            |
| `no_order`       | No       | true/false                    | none                | Only profiles who have never ordered.               |
| `timezone`       | No       | text                          | Australia/Melbourne | Sets the day boundary for the window.               |

```json theme={null}
{
  "unit": "days",
  "value": 7,
  "no_transaction": true
}
```

#### `lastShop`

Targets profiles whose last transaction date was exactly N units ago, optionally only if they have not already received a given reward since.

| Argument   | Required | Type                    | Default             | What it does                                                   |
| ---------- | -------- | ----------------------- | ------------------- | -------------------------------------------------------------- |
| `unit`     | Yes      | days/weeks/months/years | none                | Window unit.                                                   |
| `value`    | Yes      | number                  | none                | Quantity for `unit`.                                           |
| `reward`   | No       | text (reward handle)    | none                | Skip profiles already given this reward since the target date. |
| `timezone` | No       | text                    | Australia/Melbourne | Sets the day boundary for the window.                          |

```json theme={null}
{
  "unit": "weeks",
  "value": 6,
  "reward": "weve-missed-you"
}
```

### Dates and anniversaries

#### `joinAnniversary`

Targets profiles whose join anniversary (same day and month, in a later year) is today.

| Argument | Required | Type               | Default | What it does     |
| -------- | -------- | ------------------ | ------- | ---------------- |
| `tier`   | No       | text (tier handle) | none    | Limit to a tier. |

It never fires in the year the profile joined, only on later anniversaries.

```json theme={null}
{
  "tier": "platinum"
}
```

#### `upcomingBirthdays`

Targets profiles with a birthday today, or a set number of days away, who have not already had this year's birthday reward or benefit.

| Argument         | Required | Type                  | Default | What it does                                                            |
| ---------------- | -------- | --------------------- | ------- | ----------------------------------------------------------------------- |
| `same_day`       | No       | true/false            | false   | Match today's birthdays instead of a future lead day.                   |
| `days`           | No       | number (max 60)       | 7       | How many days ahead to look (ignored when `same_day` is true).          |
| `tier`           | No       | text (tier handle)    | none    | Limit to a tier.                                                        |
| `type`           | No       | `reward` or `benefit` | reward  | Which previous gift to check against, so profiles are not gifted twice. |
| `definition`     | No       | text                  | none    | For `type` of benefit: which benefit to check against.                  |
| `last_shop_days` | No       | number                | none    | Only profiles who transacted within the last N days.                    |

```json theme={null}
{
  "same_day": false,
  "days": 14,
  "last_shop_days": 365
}
```

#### `upcomingConnectedBirthMonth`

Targets profiles whose birth month is the current month, and runs the action against their linked primary account, for example to notify a parent about a dependant's birthday month.

| Argument                | Required | Type                  | Default | What it does                                                                        |
| ----------------------- | -------- | --------------------- | ------- | ----------------------------------------------------------------------------------- |
| `profile_type`          | Yes      | text                  | none    | Which profile type to match (for example `dependant`, `active`).                    |
| `type`                  | No       | `reward` or `benefit` | reward  | Which previous gift to check against.                                               |
| `definition`            | No       | text                  | none    | Which benefit to check against (for `type` of benefit).                             |
| `last_transaction_item` | No       | object                | none    | Require a recent matching transaction detail. Shape: `{ namespace, handle, days }`. |

Profiles without a linked primary account are skipped.

```json theme={null}
{
  "profile_type": "dependant",
  "type": "benefit",
  "definition": "birthday-gift"
}
```

#### `upcomingTierAnniversary`

Targets profiles whose tier anniversary is a set period away, for renewal reminders.

| Argument      | Required | Type              | Default | What it does                             |
| ------------- | -------- | ----------------- | ------- | ---------------------------------------- |
| `count`       | Yes      | number            | none    | How many units ahead the anniversary is. |
| `unit`        | Yes      | days/weeks/months | none    | Lead-time unit.                          |
| `tier_handle` | No       | list of text      | none    | Limit to these tiers.                    |

```json theme={null}
{
  "count": 1,
  "unit": "months",
  "tier_handle": ["gold", "platinum"]
}
```

### Tier, status and points

#### `profileTier`

Targets all profiles currently in a given tier.

| Argument | Required | Type               | Default | What it does       |
| -------- | -------- | ------------------ | ------- | ------------------ |
| `tier`   | Yes      | text (tier handle) | none    | The tier to match. |

```json theme={null}
{
  "tier": "gold"
}
```

#### `tierAchieved`

Targets profiles who newly reached one of the given tiers on a target day (genuine upgrades, not renewals), optionally only if they also transacted that day.

| Argument      | Required | Type                 | Default | What it does                             |
| ------------- | -------- | -------------------- | ------- | ---------------------------------------- |
| `tiers`       | Yes      | list of tier handles | none    | Tiers to match.                          |
| `count`       | Yes      | number               | none    | How many units ago the upgrade happened. |
| `unit`        | Yes      | days/weeks/months    | none    | Offset unit.                             |
| `check_spend` | No       | true/false           | none    | Also require a transaction that day.     |

```json theme={null}
{
  "tiers": ["gold"],
  "count": 1,
  "unit": "days",
  "check_spend": true
}
```

#### `profileStatuses`

Targets profiles who have held one of the given statuses for at least N days.

| Argument   | Required | Type                   | Default             | What it does                               |
| ---------- | -------- | ---------------------- | ------------------- | ------------------------------------------ |
| `statuses` | Yes      | list of status handles | none                | Statuses to match.                         |
| `days`     | Yes      | number                 | none                | Minimum days since the status was applied. |
| `timezone` | No       | text                   | Australia/Melbourne | Sets the day boundary for the window.      |

```json theme={null}
{
  "statuses": ["vip"],
  "days": 30
}
```

#### `magasinVIPStatuses`

Targets profiles holding a benefit whose definition carries a given tag, optionally split by whether the benefit has been used.

| Argument                 | Required | Type              | Default | What it does                               |
| ------------------------ | -------- | ----------------- | ------- | ------------------------------------------ |
| `benefit_definition_tag` | Yes      | text (tag handle) | none    | The tag on the benefit definition.         |
| `has_redemption`         | No       | true/false        | false   | Only benefits that have been redeemed.     |
| `no_redemption`          | No       | true/false        | false   | Only benefits that have not been redeemed. |

```json theme={null}
{
  "benefit_definition_tag": "vip",
  "no_redemption": true
}
```

#### `pointBalance`

Targets profiles whose remaining points balance for a given point definition is at least `min`, for "use your points" reminders.

| Argument                  | Required | Type                   | Default | What it does                                             |
| ------------------------- | -------- | ---------------------- | ------- | -------------------------------------------------------- |
| `min`                     | Yes      | number                 | none    | Minimum remaining balance.                               |
| `point_definition_handle` | Yes      | text                   | none    | Which point definition to total.                         |
| `statuses`                | No       | list of status handles | none    | Limit to these statuses.                                 |
| `day_of_week`             | No       | number                 | none    | Measure the balance as at this day of the previous week. |
| `timezone`                | No       | text                   | none    | Timezone for `day_of_week`.                              |

```json theme={null}
{
  "min": 500,
  "point_definition_handle": "points"
}
```

### Achievements

#### `achievementProgress`

Settles a recurring achievement: finalises the previous period's progress and rewards profiles who completed it.

| Argument             | Required | Type   | Default | What it does                                                 |
| -------------------- | -------- | ------ | ------- | ------------------------------------------------------------ |
| `achievement_handle` | Yes      | text   | none    | Which achievement to settle.                                 |
| `period`             | Yes      | text   | none    | The period being settled (`weekly`, `monthly`, or `yearly`). |
| `min_trigger`        | Yes      | number | none    | The entry-level threshold.                                   |
| `batch_size`         | Yes      | number | none    | How many profiles to process at a time.                      |

This is a heavier, batch-style automation, so set it up with care.

```json theme={null}
{
  "achievement_handle": "monthly-spend",
  "period": "monthly",
  "min_trigger": 100,
  "batch_size": 500
}
```

### Lists and inventory

#### `unpurchasedListItems`

Targets profiles with list items they have saved but not yet bought, updated recently. The unbought items are passed to the action.

| Argument                 | Required | Type              | Default | What it does                                                                                     |
| ------------------------ | -------- | ----------------- | ------- | ------------------------------------------------------------------------------------------------ |
| `count`                  | Yes      | number            | none    | How far back to look for updated items.                                                          |
| `unit`                   | Yes      | days/weeks/months | none    | Unit for `count`.                                                                                |
| `list_definition_handle` | No       | text              | none    | Limit to lists of this definition.                                                               |
| `custom_fields_filter`   | No       | object            | none    | Only lists whose custom field passes the given condition. Shape: `{ namespace, handle, logic }`. |
| `require_purchased_item` | No       | true/false        | none    | Only profiles who have bought at least one list item in the window.                              |

```json theme={null}
{
  "count": 14,
  "unit": "days",
  "list_definition_handle": "wishlist"
}
```

#### `lastStockChangeList`

Targets profiles whose listed products recently changed (back in stock, sold out, price drop, selling fast, or low stock) and are available now. The matching products are passed to the action.

| Argument      | Required | Type              | Default | What it does                                                                             |
| ------------- | -------- | ----------------- | ------- | ---------------------------------------------------------------------------------------- |
| `count`       | Yes      | number            | none    | How far back to look for the change.                                                     |
| `unit`        | Yes      | days/weeks/months | none    | Unit for `count`.                                                                        |
| `type`        | Yes      | text              | none    | Change to detect: `in_stock`, `out_stock`, `drop_price`, `selling_fast`, or `low_stock`. |
| `list_handle` | No       | text              | none    | Limit to lists with this handle.                                                         |
| `filter`      | No       | object            | none    | Extra "no other change since" condition. Shape: `{ attribute, count, unit }`.            |

Only products that are currently in stock are included.

```json theme={null}
{
  "count": 1,
  "unit": "days",
  "type": "in_stock",
  "list_handle": "wishlist"
}
```

#### `expiredReservations`

Targets product reservations older than N days, for expiry cleanup or follow-up. The action runs against the reservation, including its profile and item.

| Argument                   | Required | Type           | Default        | What it does                                       |
| -------------------------- | -------- | -------------- | -------------- | -------------------------------------------------- |
| `days`                     | Yes      | number (min 1) | none           | Reservation age threshold.                         |
| `exclude_transaction_item` | No       | true/false     | false          | Skip reservations already linked to a transaction. |
| `timezone`                 | No       | text           | client default | Day boundary for the threshold.                    |

```json theme={null}
{
  "days": 7,
  "exclude_transaction_item": true
}
```

### Advanced

#### `profileAggregation`

Targets profiles by a stored aggregate value, optionally filtered by status, for flexible segmentation.

| Argument            | Required | Type                   | Default | What it does                      |
| ------------------- | -------- | ---------------------- | ------- | --------------------------------- |
| `aggregator_name`   | Yes      | text                   | none    | The aggregate field to test.      |
| `aggregator_values` | Yes      | list                   | none    | Acceptable values for that field. |
| `statuses`          | No       | list of status handles | none    | Limit to these statuses.          |

```json theme={null}
{
  "aggregator_name": "spend_band",
  "aggregator_values": ["high", "very_high"]
}
```

#### `storeProcedure`

Runs a predefined server-side routine by name. This is for bespoke logic that does not fit the other queries; the routine must already exist on the platform.

| Argument | Required | Type | Default | What it does                    |
| -------- | -------- | ---- | ------- | ------------------------------- |
| `name`   | Yes      | text | none    | The name of the routine to run. |

```json theme={null}
{
  "name": "recalculate_tiers"
}
```

## Testing automations with dry runs

Before enabling an automation in production, trigger a dry run to simulate what it would do without creating records or firing events.

Send `POST /v3/automations/{automation}/trigger` with `dry_run: true`. Add `start_date` and `end_date` to simulate over a date range (for example, to replay a past period).

```json theme={null}
{
  "dry_run": true,
  "start_date": "2026-06-01",
  "end_date": "2026-06-07"
}
```

The endpoint returns `202 Accepted`. The simulation runs asynchronously. Once it completes, retrieve the per-profile results via the [Automation Dry Run Results API](/api-reference/automation-dry-run-result/overview).

### Dry run constraints

Not every query or action supports dry run:

* Queries that perform side effects when resolving (such as `achievementProgress` and `storeProcedure`) cannot be dry-run. Omneo returns a validation error if you attempt a dry run on an automation that uses them.
* Actions that would otherwise write production records or fire events are simulated without persisting. The `status` field on each result (`success`, `failed`, or `skipped`) shows what the action would have done.

Use `filter[automation_id]` and `filter[run_at]` when retrieving results to scope to a specific simulation. Delete results once reviewed.
