---
title: Calling the Engine API
slug: engine-api/engine-api-startup-guide
description: How to send decision requests related to Omnichannel experiences to Monetate's Engine API
docTags: 
createdAt: 2024-05-03T19:09:28.755Z
---



## Request Requirements

When an Engine API request is made, Monetate's decision engine evaluates all active Omnichannel experiences in the account and uses the provided context to make decisions about which experiences and actions for which the customer has qualified.

All Engine API requests must be made via a POST request and include the following:

- Endpoint
- Content-type header
- Body

### Endpoint

The endpoint to which Engine API requests are made is as follows:

:::CodeblockTabs
Engine API Endpoint

```none
https://engine.monetate.net/api/engine/v1/decide/{retailer_shortname}
```
:::

The `{retailer_shortname}` placeholder is a unique identifier that specifies the parent value of the account. This identifier is provided by your dedicated Services team.

A subsequent channel attribute is required within the request body that specifies the account, domain, and instance (for example `"channel": "a-887f2483/p/example.com"`).

### Content-Type Header

The content-type header is required and may be set to either `application/JSON` or `text/plain`.

Monetate recommends `text/plain` to avoid an extra round trip (the CORS preflight OPTIONS request associated with `application/JSON`).

### Body

The body of an Engine API request consists of JSON that identifies the account and passes page- and user-level data via events.

## Events in a Request

Each of the three event types instructs the Engine API to do different things with the associated information:

- Event types that begin with `monetate:decision` request that the Engine API evaluate active experiences and return actions
- Event types that begin with `monetate:context` provide information about the visitor or page that Monetate uses for targeting and decision-making purposes
- Event types that begin with `monetate:record` provide information that Monetate should record but that isn't used for targeting or decision-making purposes

All Engine API requests should follow the same structure as noted in the [API reference](docId\:CiEZ8BRuM1bICunSsjNIL). However, including various API models depends on individual integrations and use cases.

- Include the `pageType` parameter within the `monetate:context:PageView` model to use corresponding action conditions
- Include the `monetate:context:ProductThumbnailView` event to communicate all items present on a listing page or search results page, which can then be used for action conditions or advanced recommendations use cases
- Include the `monetate:context:ProductDetailView` event to communicate a product view has occurred and subsequently target/condition based on a specific product, brand, product type/category, or advanced recommendations use cases
- Include the `monetate:context:Cart` event to communicate cart contents which are used for behavioral analytics and cart-content targets or action conditions
- Include the `monetate:context:Purchase` event to communicate a purchase has occurred for behavioral analytics and purchase

See [Target, Event, & Condition Mapping](docId\:N-VumBACFtG0JlhtIkean) for more extensive mapping of Engine API models and how you can use them for targeting and action conditions in experiences and actions.

## User Identity Persistence

Monetate identifies anonymous visitors and tracks behavior via a `monetateId`. This ID is generated on the first request to the platform if it's not already present and identifies a unique device or browser.

### Monetate Tag

In a traditional [Monetate JavaScript API](docId\:zcx_p3d6ND2Rr5bJLOyUG) implementation, `monetateId` is set as a first-party cookie, `mt.v`. It persists for future site visits.

### Engine API

For Engine API implementations, Monetate generates `monetateId` if no identifier is passed in the request.

Because Monetate has no way to set the `mt.v` cookie, the requesting application is responsible for keeping track of the `monetateId` by setting the cookie or otherwise storing or maintaining the persistence of the value by other means unique to your application.

If a device ID is available that can uniquely identify the customer's device across requests, then you can alternatively include `deviceId` in all Engine API requests. This value then acts as a unique identifier and allows Monetate to track visitor behavior throughout the current session and across future sessions.

To summarize user identity persistence options for Engine API clients:

- `monetateId` — Can be used for an application and must stored in a variable on your end.
- `deviceId` — Can be used as an alternative to `monetateId` to identify the customer's device across requests that doesn't need to be stored. This value acts as a unique identifier and allows Monetate to track customer behavior throughout the current session as well as across future sessions.

:::hint{type="info"}
Whether you use `monetateId` or `deviceId` to identify the customer, you must include it in all requests for both current and future sessions.
:::

### Hybrid Implementations

For [hybrid implementations](docId\:ZFxS45Ymf6aIcWwKKgXcC), ensure that you do the following:

- If a `monetateId` exists in the `mt.v` cookie, then you must pass it in all Engine API requests.
- If no existing `monetateId` is present in an `mt.v` cookie, then you must ensure that the `monetateId` generated by the initial Engine API request is set as a first-party cookie named `mt.v` (case sensitive).

These user identity measures allow Monetate to reconcile information collected by both the Engine API and the Monetate tag into a single unified session.

:::hint{type="warning"}
You must take these measures to ensure the seamless functioning and optimal performance of your hybrid implementation. Failure to do so can result in a variety of issues, including disconnected user experiences and inaccurate data tracking.
:::

Contact your dedicated Customer Success Manager (CSM) if you need assistance with these steps.

## monetateId Sample Requests and Responses

### New Visitor Request

This example of a New Visitor request has no `monetateId`. In the response Monetate includes it.

::::CodeDrawer{title="New Visitor Request without monetateId" isResponseExpanded="true"}
:::CodeblockTabsExamples
```json
{
  "channel": "a-12345678/d/example.test",
  "events": 
  [    
    {
      "eventType": "monetate:decision:DecisionRequest",
      "requestId": "11111"
    },    
    {
      "eventType": "monetate:context:IpAddress",
      "ipAddress": "127.0.0.1"
    },    
    {
      "eventType": "monetate:context:PageView",
      "url": "https://www.example.test/path"
    }
  ]
}
```
:::

:::CodeblockTabsResponses
```javascript
{
  "meta": 
  {
    "code": 200,
    "monetateId": "5.977810341.1521134874631"
  },
  "data": 
  {
    "responses": 
    [      
      {
        "requestId": "11111",
        "actions": 
        [          
          {
            "data": 
            {
              "example": "json"
            },
            "actionType": "monetate:action:OmniJson"
          }
        ]
      }
    ]
  }
}
```
:::
::::

### Returning Visitor Request

A `monetateId` is sent in this example Returning Visitor request, which is mirrored in the response.

::::CodeDrawer{title="Returning Visitor Request with monetateId" isResponseExpanded="true"}
:::CodeblockTabsExamples
```json
{
  "channel": "a-12345678/d/example.test",
  "monetateId ": "5.977810341.1521134874631",
  "events": 
  [    
    {
      "eventType": "monetate:decision:DecisionRequest",
      "requestId": "11111"
    },    
    {
      "eventType": "monetate:context:IpAddress",
      "ipAddress": "127.0.0.1"
    },    
    {
      "eventType": "monetate:context:PageView",
      "url": "https://www.example.test/path"
    }
  ]
}
```
:::

:::CodeblockTabsResponses
```javascript
{
  "meta": 
  {
    "code": 200
  },
  "data": 
  {
    "responses": 
    [      
      {
        "requestId": "11111",
        "actions": 
        [          
          {
            "data": 
            {
              "example": "json"
            },
            "actionType": "monetate:action:OmniJson"
          }
        ]
      }
    ]
  }
}
```
:::
::::

## deviceID Sample Requests and Responses

### New Visitor Request

In this example New Visitor request, `deviceId` is passed instead of `monetateId`. In this scenario, it's a New Visitor request because Monetate hasn't received this `deviceId` before. In the response, Monetate doesn't include the `deviceID` but instead returns `monetateId`, which can be ignored in this instance.

::::CodeDrawer{title="New Visitor Request with deviceId" isResponseExpanded="true"}
:::CodeblockTabsExamples
```json
{
  "channel": "a-12345678/d/example.test",
  "deviceId ": "39hu7lgj05454nj5t4",
  "events": 
  [    
    {
      "eventType": "monetate:decision:DecisionRequest",
      "requestId": "11111"
    },    
    {
      "eventType": "monetate:context:IpAddress",
      "ipAddress": "127.0.0.1"
    },    
    {
      "eventType": "monetate:context:PageView",
      "url": "https://www.example.test/path"
    }
  ]
}
```
:::

:::CodeblockTabsResponses
```javascript
{
  "meta": 
  {
    "code": 200,
    "monetateId": "5.977810341.1521134874631"
  },
  "data": 
  {
    "responses": 
    [      
      {
        "requestId": "11111",
        "actions": 
        [          
          {
            "data": 
            {
              "example": "json"
            },
            "actionType": "monetate:action:OmniJson"
          }
        ]
      }
    ]
  }
}
```
:::
::::

### Returning Visitor Request

When the same `deviceID` is sent again, Monetate recognizes it and classifies it as a Returning Visitor. As in the response in the New Visitor request that contained a `deviceId` value, Monetate *does not* include the `deviceId` but instead returns `monetateId`.

::::CodeDrawer{title="Returning Visitor Request with deviceId" isResponseExpanded="true"}
:::CodeblockTabsExamples
```json
{
  "channel": "a-12345678/d/example.test",
  "deviceId ": "39hu7lgj05454nj5t4",
  "events": 
  [    
    {
      "eventType": "monetate:decision:DecisionRequest",
      "requestId": "11111"
    },    
    {
      "eventType": "monetate:context:IpAddress",
      "ipAddress": "127.0.0.1"
    },    
    {
      "eventType": "monetate:context:PageView",
      "url": "https://www.example.test/path"
    }
  ]
}
```
:::

:::CodeblockTabsResponses
```javascript
{
  "meta": 
  {
    "code": 200,
    "monetateId": "5.977810341.1521134874631"
  },
  "data": 
  {
    "responses": 
    [      
      {
        "requestId": "11111",
        "actions": 
        [          
          {
            "data": 
            {
              "example": "json"
            },
            "actionType": "monetate:action:OmniJson"
          }
        ]
      }
    ]
  }
}
```
:::
::::

## Custom Variables for New or Returning Visitors

You can pass `deviceId` and a custom variable in a request to let Monetate know that this customer is either a new or returning visitor.

```json
{
  "channel": "a-12345678/d/example.test",
  "deviceId ": "39hu7lgj05454nj5t4",
  "events": 
  [    
    {
      "eventType": "monetate:decision:DecisionRequest",
      "requestId": "11111"
    },    
    {
      "eventType": "monetate:context:IpAddress",
      "ipAddress": "127.0.0.1"
    },    
    {
      "eventType": "monetate:context:CustomVariables",
      "customVariables": 
      [        
        {
          "variable": "Returning_Visitor",
          "value": "True"
        }
      ]
    },    
    {
      "eventType": "monetate:context:PageView",
      "url": "https://www.example.test/path"
    }
  ]
}
```

When you first send `deviceId`, the Engine API classifies the customer as new. When you use custom variables, you send the custom variable in addition to `deviceId` to ensure that new visitors are targeted.

### Targeting New and Returning Visitors with deviceId and Custom Variables

Use the **Custom variable visitors** option in the [Landing target type](https://docs.monetate.com/docs/types-of-who-targets#landing-page-targets) to target new and returning visitors when configuring the WHO settings of an experience.

![The Custom Variable Visitors target of an experience's WHO settings, with 'New\_Visitor' in the 'Variable name' field and 'True' as the variable value](https://dyzz9obi78pm5.cloudfront.net/app/image/id/6442e3d228ea17508c7f3af4/n/experiences-who-landing-custom-variable-visitors-new-visitors-variable.png)

You can also use the **New visitors** and **Returning visitors** options in the Landing target type instead of custom variables.

![Callout of the 'New visitors' and 'Returning visitors' options on the Landing target type panel of the WHO settings of an experience](https://dyzz9obi78pm5.cloudfront.net/app/image/id/6442e3250d3a9c1b9b6dd794/n/experiences-who-landing-new-visitors-returning-visitors.png)

## Identifying Known Customers Included in a Customer Datasets

You can provide a `customerId` for logged-in customers of your application. This ID identifies someone in, for example, a loyalty program. It's associated with the identified device and allows you to use your own data, uploaded to Monetate in a [customer dataset](https://docs.monetate.com/docs/customer-data), for targeting and context.

::::ExpandableHeading
### For Customer Datasets

:::hint{type="danger"}
This content is only for clients with **Product Data** and **Customer Data** options in the **DATASETS** menu in the top navigation bar of the Monetate platform. If no menu options appear when you click **DATASETS**, then this content doesn't apply to your account. Instead, see For Customer Attributes Datasets.
:::

:::CodeblockTabs
Request with customerId from Customer Dataset

```json
{
  "channel": "a-1d121c07/p/monetate-api.myshopify.com",
  "monetateId": "5.1824559023.1570975471014",
  "customerId": "123abc",
  "events": [
    {
...
```
:::

:::hint{type="warning"}
You must send `monetateId` or `deviceId` with each request. The `customerId` cannot replace them.
:::
::::

::::ExpandableHeading
### For Customer Attributes Datasets

:::hint{type="danger"}
This content is only for clients with the one-click **DATASETS** option in the top navigation bar of the Monetate platform. If you click **DATASETS** and see **Product Data** and **Customer Data** listed as menu options, then this content doesn't apply to your account. Instead, see For Customer Datasets.
:::

If you have a Customer View enabled and have a different type of customer identifier, then continue to send `"customerId"` for the Customer View and send the Customer Attribute dataset's Identifier Name, which you can find on the [Customer Attributes view of the Datasets list page](https://docs.monetate.com/docs/datasets-list-page#customer-attributes), via a custom variable. You don't need to add the custom variable value for the Identifier Name to an experience.

:::CodeblockTabs
Request with customerId & Identifier Name in Custom Variable

```json
{
  "channel": "a-1d121c07/p/monetate-api.myshopify.com",
  "customerId": "123abc",
  "events": [
    {
      "eventType": "monetate:context:CustomVariables",
      "customVariables": [
        {
          "variable": "LoyaltyId",
          "value": "1234"
        }
      ]
    }
  ]
}
```
:::
::::

### Using Customer View with Engine API

It's possible to have a single view of a customer across mobile, desktop, and apps as long as the `customerId` is the same. Doing so stitches together the behavioral data for the customer for the corresponding behavioral targets supported by a [Customer View](https://docs.monetate.com/docs/configure-customer-view).

This setup works in Web experiences by matching on the `customerId`, which then guarantees that Monetate serves the same experience for customer A.

To have this same matching to happen in your Omnichannel experiences, then you must contact the Services team to set up an [ID Collector](https://docs.monetate.com/docs/create-an-id-collector). If your account already has an ID Collector set up for Web experiences, then provide the name so that it can be copied to your app accounts.

Client-side developers must take the following steps:

1. [Create an Omnichannel experience](https://docs.monetate.com/docs/create-an-omnichannel-experience) with the [Omni JSON action](https://docs.monetate.com/docs/omnichannel-experiences-available-action-types#omni-json) matching the desktop experience to ensure that the customer sees the same visual change.
2. Pass a `customerId` in the request along with all relevant or identical target information as context.

The Engine API responds to the request with the eligible experiences.

## Context vs Events for Analytics

Information sent to Monetate generally falls into two categories:

- **Context** — Session-derived data such as geographic and technographic information or custom variables
- **Events** — Data used for calculating analytics and key performance indicators (KPIs)

Context is determined per session and can safely be sent multiple times—by both the Monetate tag and Engine API, for example—with no effect on analytics.

However, events can potentially be recorded by both the Monetate tag and Engine API in [hybrid implementations](docId\:ZFxS45Ymf6aIcWwKKgXcC). Be aware of the following factors:

- API events are recorded at the session level for experience analytics, but you can view the aggregate count (how many times the event occurred) in raw data.
- Product views are recorded individually but are only used for processing [recommendation algorithms](https://docs.monetate.com/docs/recommendation-algorithms). What matters is if a product was viewed in a session, not how many times it was viewed.
  - The [Most Viewed (Product Detail Page)](https://docs.monetate.com/docs/recommendation-algorithms#most-viewed-product-detail-page-) recommendation algorithm can be influenced by multiple views in a given session.
  - [Collaborative recommendation algorithms](https://docs.monetate.com/docs/recommendation-algorithms#collaborative-standard-algorithms), such as Viewed and Also Viewed and Purchased and Also Purchased, aren't effected by multiple views in a given session and solely function based on whether a product was viewed in a session.
- Cart events are recorded as an event, and Monetate considers the most recent event for behavioral purposes. For this reason, even for traditional Monetate tag-based implementations, properly recording all applicable cart items on every track is important.
- Purchases are recorded individually but are deduplicated by the purchaseId value. If a Monetate tag-based integration and Engine API integration report the same purchaseId, then only one is recorded.

:::hint{type="info"}
Page views aren't currently supported by the Engine API. As a result, average page views and bounce rate metrics cannot be calculated for Omnichannel experiences.
:::

### Custom Events

You can send any event, such as clicks and impressions, that falls outside of Monetate's built-in events by using `monetate:record:PageEvents`.

:::CodeblockTabs
Example Request with monetate\:record\:PageEvents

```json
{
  "eventType": "monetate:record:PageEvents",
  "pageEvents": 
  [
    "myEvent"
  ]
}
```
:::

The list of events sent can be any event configured in Monetate by following the steps in Creating a Custom Engine API Event in this documentation. These events are identified in the API by their Unique Key, an alphanumeric string set when you create the event.

:::hint{type="warning"}
You can't use monetate\:record\:PageEvents to send an event that doesn't have a Unique Key.
:::

You can configure any event to have a Unique Key. Requests referencing this key from the time the key is set result in that event being sent to Monetate. When one or more of these events are sent via the Engine API, they're recorded within Monetate as having occurred for the customer at the time sent. For example, in the example `monetate:record:PageEvents` request, an event with the Unique Key `myEvent` is sent. This value was set using the **Unique Key** field in the Create Engine API Event modal in the Monetate platform.

A number of rules govern how Unique Keys function:

- Each key must be unique and can only be used if it actively references the event in question.
- You can't set a key retroactively but you can change it. If you send a Unique Key in a `monetate:record:PageEvents` request before you create the key, then the Unique Key is ignored.
- The Engine API also ignores any Unique Key value in a request that no longer references an event, such as when an Unique Key is changed.

Custom events are useful for reporting and for use as goal metrics in Monetate experiences.

### Creating a Custom Engine API Event

Follow these steps to create a custom Engine API event in the Monetate platform.

1. Click **COMPONENTS** in the top navigation bar and then select **Events**.

   ![Callout of the Events option in the COMPONENTS menu in the top navigation bar of the Monetate platform](https://dyzz9obi78pm5.cloudfront.net/app/image/id/6453ef3af6a6be167836a733/n/components-components-to-events.png)
2. Click the arrow to the right of **CREATE EVENT** and then select **Create Engine API Event**.

   ![Callout of the Create Engine API Event option in the CREATE EVENT selector](https://dyzz9obi78pm5.cloudfront.net/app/image/id/6453f1c5e5dfd8198618d8b2/n/events-list-page-create-event-create-engine-api-event.png)
3. In the Create Engine API Event modal, give the event a title and description, then enter into **Unique Key** the value to be sent when this event occurs. Leave **API** as the selected option for **Category**. Optionally, enter a subcategory and any [action conditions](https://docs.monetate.com/docs/action-conditions).

   ![The Create Engine API Event modal](https://dyzz9obi78pm5.cloudfront.net/app/image/id/6453f31a68f32229523e85a3/n/events-list-page-create-event-create-engine-api-event-modal.png)


4. &#x20;Click **Save**.

:::hint{type="info"}
Monetate recommends creating one or more action conditions to limit the event to pages on which it should be tracked.
:::

When a customer meets the criteria of the event, send a request with `monetate:record:PageEvents` that contains the Unique Key that you input for the custom event.

You also must add the custom API event to the WHY settings of an Omnichannel experience as a secondary metric. Follow steps 5 and 6 in [Add Custom Metrics to an Experience](https://docs.monetate.com/docs/add-custom-metrics-to-an-experience) in the Monetate Knowledge Base to add and select the event in the Experience Editor.

## Managed Impressions

By default, when a request with `monetate:decision:DecisionRequest` is made and an action is returned as part of the Engine API response, an impression is recorded for that action at decision time.

In some situations additional front-end logic must be applied for a customer to qualify for a particular action, such as expanding a navigation bar to see additional options. In cases such as this one, you can use a `managed_impressions` action.

:::hint{type="info"}
Action templates with `managed_impressions` must be added to individual accounts. Contact your dedicated Customer Success Manager for assistance.
:::

Action templates support a `managed_impressions` flag. When this flag is set to true, the action isn't recorded at decision time.

This flag allows you to set additional action conditions beyond those Monetate is able to evaluate. Even without action conditions, it allows the caller to detect the actual visibility of the action and record its impression accordingly.

For example, an action may adjust the display of options in a drop-down menu, but the customer must first click the menu to become eligible to see the action. This screenshot shows the Omni JSON Managed Impression action template configured for this scenario.

![The Omni JSON Managed Impression action template configured for an action that requires a customer to click a menu](https://dyzz9obi78pm5.cloudfront.net/app/image/id/6453fd87dabeb83466542b7e/n/experiences-omni-what-omni-json-managed-impressions.png)

When you make a request to the Engine API, the initial response contains the experience with managed impression action and a unique impressionId for the visitor in the session.

::::CodeDrawer{title="monetate:record:Impressions Request" isResponseExpanded="true"}
:::CodeblockTabsExamples
```json
{
  "monetateId": "5.977810341.1521134874631",
  "channel": "a-12345678/d/example.test",
  "events": 
  [    
    {
      "eventType": "monetate:record:Impressions",
      "impressionIds": 
      [
        "2.MTY3MTE3Ni4xLjE2MjE0MjcyODE",
        "2.MbV8QjE1MTQ4MDg5MDA"
      ]
    }
  ]
}
```
:::

:::CodeblockTabsResponses
```javascript
{
  "meta": 
  {
    "code": 200,
    "monetateId": "5.977810341.1521134874631"
  },
  "data": 
  {
    "responses": 
    [      
      {
        "requestId": "11111",
        "actions": 
        [          
          {
            "impressionId": "2.MTY3MTE3Ni4xLjE2MjE0MjcyODE",
            "json": 
            {
              "ClickedElement": "true"
            },
            "actionType": "monetate:action:OmnichannelJson",
            "actionId": 3813493,
            "isControl": true
          }
        ]
      }
    ]
  }
}
```
:::
::::

Each action returned in the response includes two additional fields:

- The `impressionId` field contains an encoded string that must be passed back to Monetate when the customer qualifies for all front-end conditions associated with the action (for example, the customer has clicked a drop-down menu and is now eligible to see an action that modifies options within the menu).
- The `isControl` field contains a Boolean value that indicates whether the customer has been assigned to the control group for the action. Regardless of whether `isControl=true`, the `impressionId` value should be reported back to Monetate once the customer meets all eligibility criteria. However, if `isControl=true` then the action doesn't display for the visitor.

Once a customer meets all eligibility criteria, the `impressionId` value must be reported back to Monetate so that it can record the impression. The same `monetateId` or `deviceId` used in the initial request must be passed when recording impressions so that they can be associated with the customer's session. Multiple `impressionId` strings can be reported in the same Engine API call so long as they're associated with the same visitor.

:::CodeblockTabs
Example Second Managed Impressions Response

```json
{
  "meta": 
  {
    "code": 200,
    "errors": []
  },
  "data": 
  {
    "responses": []
  }
}
```
:::

## Request Filtering

The `monetate:decision:DecisionRequest` event supports two types of filtering:

- The `slots=[]` attribute expects an array of strings, each of which is a slot name for an Engine API action (for example, `omni_redirect`). Only actions that have slot names matching one of the specified slots are evaluated, and for each slot the highest-priority action matching that slot is returned.
- The `actionTypes=[]` attribute expects an array of strings, each of which is an action type for an Engine API action (for example, `monetate:action:OmnichannelJson`). Only actions that have an action type matching one of the specified action types are evaluated. Unlike the slot filters, it's possible to qualify for multiple actions with the same action type.

If the `slots` attribute is missing or consists of an empty array, then no slot filtering is performed. If the `actionTypes` attribute is missing or consists of an empty array, then no action type filtering is performed. If both `slots` and `actionTypes` are specified, then actions must match both the `slots` and `actionTypes` filters to be evaluated.

In this `monetate:decision:DecisionRequest` example request, the event considers only Omnichannel redirect actions using the `slots=[]` approach.

:::CodeblockTabs
Example monetate\:decision\:DecisionRequest with Request Filtering

```json
{
  "channel": "a-12345678/d/example.test",
  "events": 
  [    
    {
      "eventType": "monetate:decision:DecisionRequest",
      "requestId": "1111111",
      "slots": 
      [
        "omni_redirect"
      ]
    },    
    {
      "eventType": "monetate:context:PageView",
      "pageType": "homepage"
    }
  ]
}
```
:::

## Redirect Actions

When a `monetate:decision:DecisionRequest` event that doesn't include slot filtering is submitted, the customer might qualify for redirect actions, non-redirect actions, or some combination of the two:

- If the customer qualifies for a redirect action and is assigned to the experiment group, then only that action is returned in the response.
- If the customer qualifies for multiple redirect actions and is assigned to the experiment group for each of them, then the action with the highest priority is returned.
- If the customer doesn't qualify for any redirect actions or is assigned to the control group for all redirect actions they do qualify for, then all non-redirect actions are returned.

Single-request full-page redirects also work when the `monetate:decision:DecisionRequest` event includes the attribute `managedImpressions=True`:

- If the customer qualifies for a redirect action and is assigned to the experiment group, only that action is returned in the response. The action includes an `impressionId` token that should be reported back to Monetate when the redirect occurs.
- If the customer qualifies for a redirect action but is assigned to the control group, that redirect action is still included in the response and has an associated `impressionId` token, but the response indicates that it's a control action with the `isControl=True` flag.

The `impressionId` token for a given redirect action must be reported back to Monetate regardless of whether the customer is in the experiment group or the control group. See [Managed Impressions](./#managed-impressions) in this documentation for details about when and how to report the impressionId token.

:::hint{type="info"}
The customerr should only be redirected to the URL included in the action if `isControl=False`.
:::

:::CodeblockTabs
Example Client-Side Logic

```json
# Determine whether a redirect action exists among the actions in the response 
for action in actions: 
    if action['actionType'] == 'monetate:action:OmnichannelRedirect': 
      # Report the impression regardless of whether the user 
      # is in the experiment group or control group 
      report_impression(action['impressionId']) 
  
      # Only redirect if the user is in the experiment group 
      if not action['isControl']: 
          redirect_to_url(action['url'])
```
:::

## Third-Party Analytics

For Monetate tag–based experiences, third-party analytics integrations can be set up that execute client-side and send reporting labels directly to a vendor (for example, Google Analytics). Only experiences for which third-party reporting is enabled have their labels submitted.

For Engine API experiences, no formal third-party integrations are available. Instead, the Engine API response can include reporting data, and the requesting application is responsible for passing the data along to the preferred third-party analytics provider. These labels are made available when the `includeReporting=true` flag is added to the `monetate:decision:DecisionRequest` event.

::::CodeDrawer{title="monetate:decision:DecisionRequest for Reporting Labels" isResponseExpanded="true"}
:::CodeblockTabsExamples
```json
{
  "channel": "a-12345678/d/example.test",
  "monetateId ": "5.977810341.1521134874631",
  "events": 
  [    
    {
      "eventType": "monetate:decision:DecisionRequest",
      "requestId": "11111",
      " includeReporting ": true
    },    
    {
      "eventType": "monetate:context:IpAddress",
      "ipAddress": "127.0.0.1"
    },    
    {
      "eventType": "monetate:context:PageView",
      "url": "https://www.example.test/path"
    }
  ]
}
```
:::

:::CodeblockTabsResponses
```javascript
{
  "meta": 
  {
    "code": 200
  },
  "data": 
  {
    "responses": 
    [      
      {
        "requestId": "11111",
        "actions": 
        [          
          {
            "actionType": "monetate:action:OmnichannelJson",
            "impressionReporting": 
            [              
              {
                "experience_label": "omni-TPA-test-1",
                "variant_label": "B",
                "is_control": false
              }
            ]
          }
        ]
      }
    ]
  }
}
```
:::
::::

## Example Request with Annotations

The following code shows an example request. Each object is described separately afterward.

:::CodeblockTabs
Example Engine API Request

```json
{
  "deviceId": "IMEI-123456789",
  "monetateId": "2.309132816.1519728587304",
  "preview": "6.3.eJyrVkpMTs4vzSuJz0xRsj...",
  "customerId": "87654321",
  "channel": "a-76ca7dd3/p/example.com",
  "events": 
  [    
    {
      "eventType": "monetate:decision:DecisionRequest",
      "requestId": "12345678",
      "filters": 
      [
        "slot_name"
      ],
      "manageImpressions": false,
      "includeReporting": true
    },    
    {
      "eventType": "monetate:context:IpAddress",
      "ipAddress": "79.173.135.170"
    },    
    {
      "eventType": "monetate:context:Coordinates",
      "latitude": "49.566667",
      "longitude": "10.883333"
    },    
    {
      "eventType": "monetate:context:UserAgent",
      "userAgent": "Mozilla/5.0 (Macintosh; U; Intel Mac OS X; en) AppleWebKit/522.11 (KHTML, like Gecko) Safari/3.0.2"
    },    
    {
      "eventType": "monetate:context:ScreenSize",
      "width": 1024,
      "height": 762
    },    
    {
      "eventType": "monetate:context:Metadata",
      "metadata": 
      {
        "language": "en-GB"
      }
    },    
    {
      "eventType": "monetate:context:CustomVariables",
      "customVariables": 
      [        
        {
          "variable": "VariableName",
          "value": "VariableValue"
        }
      ]
    },    
    {
      "eventType": "monetate:context:PageView",
      "url": "https://www.example.com/search",
      "pageType": "search"
    },    
    {
      "eventType": "monetate:context:Referrer",
      "referrer": "http://www.example.com"
    },    
    {
      "eventType": "monetate:record:PageEvents",
      "pageEvents": 
      [
        "myEvent"
      ]
    },    
    {
      "eventType": "monetate:context:ProductThumbnailView",
      "products": 
      [
        "product72",
        "product43",
        "product42"
      ]
    },    
    {
      "eventType": "monetate:context:ProductDetailView",
      "products": 
      [        
        {
          "productId": "product72",
          "sku": "product72-large-green"
        },        
        {
          "productId": "product43",
          "sku": "product43-medium-striped"
        },        
        {
          "productId": "product57"
        }
      ]
    },    
    {
      "eventType": "monetate:context:Cart",
      "cartLines": 
      [        
        {
          "sku": "product72color2",
          "pid": "product72",
          "quantity": 2,
          "currency": "GBP",
          "value": "24.00"
        }
      ]
    },    
    {
      "eventType": "monetate:context:Purchase",
      "purchaseId": "123456789",
      "purchaseLines": 
      [        
        {
          "sku": "product72color2",
          "pid": "product72",
          "quantity": 2,
          "currency": "GBP",
          "value": "24.00"
        }
      ]
    },    
    {
      "eventType": "monetate:record:Impressions",
      "impressionIds": 
      [
        "2.MS4xLjE1MTQ4MDg5MDA"
      ]
    }
  ]
}
```
:::

### Objects

**`deviceId`** — Can be sent with new visitors without `mt.v`, but is normally used for apps and similar deployments in which cookie IDs are not possible (targeting, conditioning)

```json
"deviceId": "IMEI-123456789"
```

**`mt.v` value** — If not provided, one is returned and the session is considered as a new visitor for targeting and analytics

```json
"monetateId": "2.309132816.1519728587304"
```

**`preview` flag** — If the session is a preview, include the token ID for this object for experience and split preview

```json
"preview": "6.3.eJyrVkpMTs4vzSuJz0xRsj..."
```

**`customerId`** — Unique identifier for Customer View and Customer Datasets

```json
"customerId": "87654321"
```

**`channel`** — Monetate account information

```json
"channel": "a-76ca7dd3/p/example.com"
```

### Events

The following objects are data passed to Monetate for experiences and analytics.

**`monetate:decision:DecisionRequest`** — Decision request with possible filtering for certain action types, managed impressions, and whether to include reporting in the response; the `filters` parameter can be used to filter certain action types

```json
{
  "eventType": "monetate:decision:DecisionRequest",
  "requestId": "12345678",
  "filters": 
  [
    "slot_name"
  ],
  "manageImpressions": false,
  "includeReporting": true
}
```

**`monetate:context:IpAddress`** — The IP address (for targeting and analytics)

```json
{
  "eventType": "monetate:context:IpAddress",
  "ipAddress": "79.173.135.170"
}
```

**`monetate:context:Coordinates`** — Physical coordinates (for targeting and analytics)

```json
{
  "eventType": "monetate:context:Coordinates",
  "latitude": "49.566667",
  "longitude": "10.883333"
}
```

**`monetate:context:UserAgent`** — User agent header (for targeting and analytics)

```json
{
  "eventType": "monetate:context:UserAgent",
  "userAgent": "Mozilla/5.0 (Macintosh; U; Intel Mac OS X; en) AppleWebKit/522.11 (KHTML, like Gecko) Safari/3.0.2"
}
```

**`monetate:context:ScreenSize`** — Size of the screen the customer is viewing (for targeting)

```json
{
  "eventType": "monetate:context:ScreenSize",
  "width": 1024,
  "height": 762
}
```

**`monetate:context:Metadata`** — Client-specific metadata (for targeting and conditioning)

```json
{
  "eventType": "monetate:context:Metadata",
  "metadata": 
  {
    "language": "en-GB"
  }
}
```

**`monetate:context:CustomVariables`** — Custom variables (for targeting)

```json
{
  "eventType": "monetate:context:CustomVariables",
  "customVariables": 
  [    
    {
      "variable": "VariableName",
      "value": "VariableValue"
    }
  ]
}
```

**`monetate:context:PageView`** — Page view and type (for conditioning)

```json
{
  "eventType": "monetate:context:PageView",
  "url": "https://www.example.com/search",
  "pageType": "search"
}
```

**`monetate:context:Referrer`** — Referrer (for targeting and conditioning)

```json
{
  "eventType": "monetate:context:Referrer",
  "referrer": "http://www.example.com"
}
```

**`monetate:record:PageEvents`** — Custom page events (for analytics)

```json
{
  "eventType": "monetate:record:PageEvents",
  "pageEvents": 
  [
    "myEvent"
  ]
}
```

**`monetate:context:ProductThumbnailView`** — Search and product listing page (PLP) product view (for targeting and conditioning)

```json
{
  "eventType": "monetate:context:ProductThumbnailView",
  "products": 
  [
    "product72",
    "product43",
    "product42"
  ]
}
```

**`monetate:context:ProductDetailView`** — Product detail page (PDP) product view (for targeting and conditioning)

```json
{
  "eventType": "monetate:context:ProductDetailView",
  "products": 
  [    
    {
      "productId": "product72",
      "sku": "product72-large-green"
    },    
    {
      "productId": "product43",
      "sku": "product43-medium-striped"
    },    
    {
      "productId": "product57"
    }
  ]
}
```

**`monetate:context:Cart`** — Cart contents (for targeting, conditioning, and analytics)

```json
{
  "eventType": "monetate:context:Cart",
  "cartLines": 
  [    
    {
      "sku": "product72colour2",
      "pid": "product72",
      "quantity": 2,
      "currency": "GBP",
      "value": "24.00"
    }
  ]
}
```

**`monetate:context:Purchase`** — Products purchased (for targeting and analytics)

```json
{
  "eventType": "monetate:context:Purchase",
  "purchaseId": "123456789",
  "purchaseLines": 
  [    
    {
      "sku": "product72colour2",
      "pid": "product72",
      "quantity": 2,
      "currency": "GBP",
      "value": "24.00"
    }
  ]
}
```

**`monetate:record:Impressions`** — When `manageImpressions` is set to `true`, this event tells Monetate that the impression happened

```json
{
  "eventType": "monetate:record:Impressions",
  "impressionIds": 
  [
    "2.MS4xLjE1MTQ4MDg5MDA"
  ]
}
```

