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

# Triggers

> Which checkout calls a function intercepts: the trigger URL, the HTTP method, the request/response type, and the JSONata condition the Admin builds for you

A trigger has two parts: a **URL** the function watches, and an **expression** that must be true for the function to run. The Admin builds both from a form; the CLI takes them as flags.

![Function trigger configuration](https://mintcdn.com/ollie/ZKpSeyUd64Smy50J/images/admin-function-general.png?fit=max\&auto=format\&n=ZKpSeyUd64Smy50J\&q=85\&s=3ccba11d5e2a2f10a3e55d5d8893c9ba)

Trigger Configuration and Trigger Variables in the Admin

## The URL

* **Provider VTEX** locks the prefix to your account, `https://<account>.vtexcommercestable.com.br/api/`, and you type the rest, for example `checkout/pub/orderForm`.
* **Provider Custom** takes any absolute URL, for calls a component makes through the `REQUEST` action.

The function runs for calls whose **origin** (scheme, host, port) is exactly the trigger's and whose **path** matches the trigger's path. The query string is ignored. The path can contain parameters:

| Pattern | Matches | Does not match |
| - | - | - |
| `checkout/pub/orderForm` | `/api/checkout/pub/orderForm` (any case, optional trailing slash) | `/api/checkout/pub/orderForm/abc` |
| `checkout/pub/orderForm/:id` | `/api/checkout/pub/orderForm/abc` | `/api/checkout/pub/orderForm/abc/items` |
| `checkout/pub/orderForm/:id/items` | `/api/checkout/pub/orderForm/abc/items` | `/api/checkout/pub/orderForm/abc/items/update` |
| `checkout/pub/orderForm/*rest` | everything under `/api/checkout/pub/orderForm/` | `/api/checkout/pub/orderForm` itself |

`:name` matches exactly one segment and `*name` matches one or more. Optional groups and bare `*` are not supported; to cover a path and everything under it, create two functions. A relative URL is accepted by the CLI but never matches; always use the absolute URL.

## The expression

The expression is written in [JSONata](https://jsonata.org/) and evaluated against this object:

```json theme={"system"}
{
  "method": "POST",
  "headers": { "content-type": "application/json", "...": "..." },
  "request": { "headers": { "x-ollie-request-action": "addCartItems", "...": "..." } },
  "body": { "...": "the parsed JSON body, or the raw text" },
  "status": 200
}
```

* `method`: the HTTP method of the request.
* `headers`: for a **request** function, the request headers; for a **response** function, the **response** headers. Header names are lowercase.
* `request.headers`: the request headers, in both cases. Use this one when you filter on something the checkout sent.
* `body`: for a request function the request body, for a response function the response body. Parsed as JSON when the content type is `application/json`, otherwise the raw text. A `GET` has `""`.
* `status`: the response status code; `undefined` for request functions.

The function runs only when the expression evaluates to exactly `true`. An expression that cannot be evaluated (a syntax error, or a comparison on a missing nested value) counts as a function error and follows the function's error behaviour.

### What the Admin generates

The **HTTP Method** chips become `method in ["GET", "POST"]`. Each **Condition** row becomes a comparison, **Only for successful response (2xx)** adds `status >= 200 and status < 300`, and the **Code** tab's custom filter is appended. All parts are joined with `and`; the **Generated expression** box shows the result, which is what gets saved.

![Function trigger code view](https://mintcdn.com/ollie/ZKpSeyUd64Smy50J/images/admin-function-trigger-code.png?fit=max\&auto=format\&n=ZKpSeyUd64Smy50J\&q=85\&s=1360666461c56d2840b7a01a0df4fbe2)

The Code tab: a raw JSONata filter appended to the visual conditions

### Useful expressions

Run on the add-to-cart call only (the checkout tags its mutations with the `x-ollie-request-action` header):

```text theme={"system"}
method in ["POST"] and request.headers.`x-ollie-request-action` = "addCartItems"
```

Run on successful responses that contain an item with more than five units:

```text theme={"system"}
status >= 200 and status < 300 and $count(body.items[quantity > 5]) > 0
```

Run on every call except the one that places the order. The header is absent on plain reads, so test for its existence first:

```text theme={"system"}
$exists(request.headers.`x-ollie-request-action`) = false or request.headers.`x-ollie-request-action` != "createOrder"
```

> [!NOTE]
>
> Use the `$exists(...)` form whenever the header may be absent, for example on plain `GET` calls, so the condition is true rather than undefined.

The header values the checkout sends: `createCheckoutSession`, `refreshCartOutdated`, `addCartItems`, `removeCartItems`, `updateCartItemsQuantity`, `clearCartItems`, `clearMessages`, `updateCoupons`, `updateGiftCards`, `updateShippingPackages`, `updateShippingAddresses`, `selectPickupPoint`, `simulateCheckoutSession`, `updatePaymentMethods`, `updateCustomerDetails`, `updateCustomerPreferences`, `createOrder`.

## Which calls can be intercepted

Only calls made by the checkout **server** reach the hub. For a VTEX store these are the main ones (all under `https://<account>.vtexcommercestable.com.br/api/`):

| Path | When |
| - | - |
| `checkout/pub/orderForm` | A new cart is created |
| `checkout/pub/orderForm/:id` | The session is loaded or refreshed |
| `checkout/pub/orderForm/:id/items`, `.../items/update`, `.../items/removeAll` | Items added, quantities changed, cart cleared |
| `checkout/pub/orderForm/:id/coupons` | Coupons applied or removed |
| `checkout/pub/orderForm/:id/attachments/clientProfileData` | Customer details saved |
| `checkout/pub/orderForm/:id/attachments/clientPreferencesData` | Customer preferences saved |
| `checkout/pub/orderForm/:id/attachments/shippingData` | Address or shipping option saved (also right before the order is placed) |
| `checkout/pub/orderForm/:id/attachments/paymentData` | Payment method selected |
| `checkout/pub/orderForm/:id/attachments/marketingData` | Marketing data saved |
| `checkout/pub/orderForm/:id/transaction` | The order is placed (`createOrder`) |
| `checkout/pub/orderForms/simulation` | A simulation runs |
| `checkout/pub/pickup-points` | Pickup points are searched |
| `checkout/pub/orders/order-group/:group` | The order confirmation page loads |

Plus any absolute URL a custom component sends through `useCheckoutAction("REQUEST")`, which is how you call your own endpoints from the checkout and still run functions on them.

**Not intercepted:** the card payment submission (sent from the browser to the payment vault), installment lookups, order-status polling for PIX and wallets, and anything the shopper's browser fetches on its own.

## Activation and caching

A function runs only when it is **Active**, has a trigger, and has a deployed build. The hub caches the list of a store's active functions for up to **3 minutes**, so a change to the trigger, priority or active flag can take that long to apply. New code is picked up immediately after a successful build.

## Related

* [Writing a function](/ollie-shop/functions/writing-a-function.md): what to do once the trigger matched
* [Record commands](/ollie-shop/cli/resources.md#function): setting a trigger with `--trigger-url` and `--trigger-expression`


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