About user events

This page describes the user event object, including listing potential user event types, and provides sample data for all user event types.

Retail uses real-time user events to generate recommendations and search results. When you upload data to the Retail API, both Recommendations and Retail Search are able to use that data, so you don't need to upload the same events twice if you use both services.

For help with recording user events, see Record real-time user events.

User event types

There are several user event types that you can record as users browse your retail site:

User event name User action
add-to-cart Adds product to cart.
category-page-view Views special pages, such as sale or promotion pages.
detail-page-view Views product detail page.
home-page-view Views homepage.
purchase-complete Completes checkout.
search Searches the catalog.
shopping-cart-page-view Views shopping cart.

For detailed information about the UserEvent object, see UserEvent.

Event type priority

For the highest quality results, we recommend that you record user events for all event types. The following table describes the priority of the different user event types. You must log the highest priority user events to achieve quality data models.

Priority User Events
Required for initial live experiment

add-to-cart

detail-page-view

purchase-complete

home-page-view (for Recommendations)

search (for Retail Search)

Important for improving Recommendations model quality over time

category-page-view

search

shopping-cart-page-view

User event requirements and best practices

The following tables list requirements and best practices for user event types that Recommendations and Retail Search use. Check that your user events fulfill these requirements so that the Retail API can generate quality results.

This section lists:

If you use Recommendations models, also see Model type data requirements, which lists additional requirements depending on the recommendation model type and optimization objective you plan to use.

You can view data quality metrics for Retail Search on the Data quality page in the Retail console. These metrics show the percentages of products and user events that fulfill recommended standards of data quality. For information about how to view search data quality, see Unlock search performance tiers.

Retail API requirements

Make sure your user events meet the following requirements so that the Retail API can generate quality results. These apply to both Recommendations and Retail Search.

Event type Requirement Impact
All events

Do not include synthetic data or duplicate events.

Synthetic or duplicate events negatively impact model quality and often prevent successful model training. Duplicate events can cause incorrect metrics values.

Include at least 100 unique visitor IDs for each type of event ingested.

This ensures the Retail API has enough data to generate quality results.

Visitor IDs must be formatted exactly the same across event import or event recording and in Retail API requests.

Using a consistent format for visitor IDs helps the Retail API correctly identify visitor patterns and provide better-quality results based on user behavior.

Products included in the events should exist in your catalog of products.

The unjoined events ratio should be kept as low as possible. A high ratio can negatively impact the quality of recommendation or search results.

Unjoined event data is not used to train models. However, unjoined events can be joined later, after the associated products have been ingested. For more information, see Rejoin user events.

Some user events should have the same visitor ID.

To construct valid behavior sequence histories, Retail must be able to see multiple events with the same visitor ID.

For example, visitor123 has viewed five product detail pages, added three products to their cart, then bought two of the original five products. If these events all provide the same consistently formatted visitor ID, Retail can consider that behavior sequence in its models.

detail-page-view

Include exactly one product per event.

The event can't be used if no product exists. If multiple products are included, the event is malformed and can't be used.

add-to-cart

Include exactly one product per event.

If multiple products are included, the event is malformed and can't be used.

purchase-complete

Include purchase_transaction.revenue.

purchase-complete events that are missing the revenue field are not used to train models.

Include exactly one purchase_transaction.currency_code across all purchase events.

There is no default currency code; a code must be supplied.

Purchase events without this field result in incorrect revenue metrics.

Check that some purchase events include multiple products.

Having some purchase events with multiple products helps the model learn co-purchase patterns.

Recommendations-specific requirements

If you are using Recommendations, make sure your user events meet the following requirements.

If you use Recommendations models, also see Model type data requirements, which lists additional requirements depending on the recommendation model type and optimization objective you plan to use.

Event type Requirement Impact
purchase-complete

Do not flatten multi-item baskets into multiple purchase events. They should remain as single purchase events that include multiple products.

This ensures that valid co-purchase patterns are generated.

Retail Search requirements

If you are using Retail Search, make sure your user events meet the following minimum requirements to get results.

Event type Requirement Impact
search

searchQuery must exist for search events, and pageCategories must exist for browsing events.

Not including this field can have a severe negative impact on search result quality and metrics.

The visitor ID in search requests should match the visitor ID sent in events related to that search request.

If they don't match, the events are malformed and metrics could be incorrect.

The list of product IDs in search events must match the list of products shown to the user in its entirety.

If they don't match, the negative impact to search result quality can be severe, and metrics will be incorrect.

If the search uses a filter, filter must exist and parse correctly.

If this field does not exist, the Retail API can't use the filter part of the data, which can negatively impact search result quality.

Include the attribution_token field to link other events back to search events.

Not including a search token has a severe negative impact on search quality and metrics accuracy.

Search optimization requirements

To let Retail Search automatically optimize the search experience based on overall user trends, upload the following data.

Events should be uploaded at least daily with a maximum delay of 24 hours.

Events metric Events volume/frequency Description
Volume of search events 2,000,000 in last 90 days

At least 2 million events in the last 90 days are required to optimize the search experience based on events ingested.

We recommend uploading events at least daily to maintain good data quality. During historical event imports make sure that data distribution skews toward the most recent timestamp. The number of events on the last timestamp day should be equal to or more than the average daily event count.

Volume of detail-page-view attributable to a search event 500,000 in last 30 days At least 500,000 events are required for optimizing search results using user events.
Average detail-page-view events attributable to a search event per product 10 in last 30 days Required for optimizing search results using the events ingested unless events for past 21 days are uploaded.
Proportion of search events with parseable filters 0.1 in last 30 days Recommended for optimizing the order of dynamic facets in the search response.
Proportion of searched products with price 0.95 in last 30 days Required for optimizing search results using the events ingested.
Average add-to-cart events attributable to a search event per priced product 0.5 in last 30 days Recommended for revenue optimized search results.
Average purchase-complete events attributable to a search event per searchable priced product 0.5 in last 30 days Recommended for revenue optimized search results.

Search personalization requirements

Retail Search requires the following data to personalize text search and browse search results for your users based on their activity.

After you upload the following data, Retail Search can personalize results automatically.

Events metric Events volume/frequency Description
Volume of search events served by Retail Search 100,000 in last 30 days

At least 100,000 events served by Retail Search in the last 30 days are required to provide personalization.

Retail Search results are not cached Less than 1% of the most recent 100,000 user events

Do not cache Retail Search results for text search or browse searches if you plan to use personalization. Reusing the same results across visitors prevents Retail Search from providing truly personalized results to any given user and risks exposing users' private data. Retail Search automatically turns off personalization if caching is detected.

If you cache only search results, Retail Search can still personalize browse results. Conversely, if you cache only browse results, Retail Search can still personalize text query search results.

Visitor ID matches between SearchRequests and user events More than 10% match for the most recent 100,000 user events Make sure that visitor ID spacing and formatting matches across SearchRequests and user events. Consistent visitor ID formatting ensures that Retail Search can identify user activity correctly.

User event type examples and schemas

This section provides the data formats for each event type supported by the Retail API.

Examples for JavaScript Pixel and Tag Manager are provided. For BigQuery, the full table schema for each type is provided.

For all user events types, userId is optional. The product information fields (priceInfo and availability) are optional.

Note that:

  • The experimentIds field is needed only if you are running an A/B experiment.
  • The attributionToken field is optional; it is used to measure performance. predict, search and detail-page-view events that are generated from Retail API clicks should have an attribution token in order to link the events back to the searches or recommendations that generated them.
  • Make sure your events all use a single currency, especially if you plan to use Google Cloud console to get revenue metrics. The Retail API does not support using multiple currencies per catalog.

For more details about the user event object, see the UserEvent API reference documentation.

Add to cart

The following shows the add-to-cart user event format.

Minimum required add-to-cart object

The following examples show only the required fields of the add-to-cart user event format.

When you import events, you must provide the timestamp in the eventTime field in the format specified by RFC 3339.

Other fields might be required depending on the API method used or if additional fields are used. (For example, if the user event is associated with an entity, make sure to specify the entity field.) For full details of each field and when they are required, see the UserEvent API reference documentation.

JavaScript Pixel

var user_event = {
  "eventType": "add-to-cart",
  "visitorId": "visitor-id",
  "productDetails": [{
    "product": {
      "id": "product-id"
    },
    "quantity": product-quantity
  }]
};

Tag Manager

<script>
    dataLayer = dataLayer || [];
    dataLayer.push({
      'cloud_retail': {
        'eventType': 'add-to-cart',
        'visitorId': 'visitor-id',
        // You can also define the visitor ID
        // directly on the Tag Manager tag.
        'productDetails': [{
          'product': {
            'id': 'product-id'
          },
          'quantity': product-quantity
        }]
      }
    });
</script>

BigQuery

This is the complete JSON schema for this user event type. Specify this schema when creating tables for this user event type in BigQuery.

Modes for required fields are set to REQUIRED or REPEATED. Modes for optional fields are set to NULLABLE.

Note that eventTime is required for importing events with BigQuery. eventTime is a string with a Timestamp format.

[
 {
   "name": "eventType",
   "type": "STRING",
   "mode": "REQUIRED"
 },
 {
   "name": "visitorId",
   "type": "STRING",
   "mode": "REQUIRED"
 },
 {
   "name": "eventTime",
   "type": "STRING",
   "mode": "REQUIRED"
 },
 {
   "name": "experimentIds",
   "type": "STRING",
   "mode": "REPEATED"
 },
 {
   "name": "attributionToken",
   "type": "STRING",
   "mode": "NULLABLE"
 },
 {
   "name": "productDetails",
   "type": "RECORD",
   "mode": "REPEATED",
   "fields": [
     {
       "name": "product",
       "type": "RECORD",
       "mode": "REQUIRED",
       "fields": [
         {
           "name": "id",
           "type": "STRING",
           "mode": "REQUIRED"
         }
       ]
     },
     {
       "name": "quantity",
       "type": "INTEGER",
       "mode": "REQUIRED"
     }
   ]
 },
 {
   "name": "cartId",
   "type": "STRING",
   "mode": "NULLABLE"
 },
 {
   "name": "userInfo",
   "type": "RECORD",
   "mode": "NULLABLE",
   "fields": [
     {
       "name": "userId",
       "type": "STRING",
       "mode": "NULLABLE"
     },
     {
       "name": "ipAddress",
       "type": "STRING",
       "mode": "NULLABLE"
     },
     {
       "name": "userAgent",
       "type": "STRING",
       "mode": "NULLABLE"
     },
     {
       "name": "directUserRequest",
       "type": "BOOLEAN",
       "mode": "NULLABLE"
     }
   ]
 },
 {
   "name": "uri",
   "type": "STRING",
   "mode": "NULLABLE"
 },
 {
   "name": "referrerUri",
   "type": "STRING",
   "mode": "NULLABLE"
 },
 {
   "name": "pageViewId",
   "type": "STRING",
   "mode": "NULLABLE"
 },
 {
   "name": "entity",
   "type": "STRING",
   "mode": "NULLABLE"
 }
]

Category page view

The following shows the category-page-view user event format.

Minimum required category-page-view object

The following examples show only the required fields of the category-page-view user event format.

While there is usually only one category associated with a page, the pageCategories field also supports a category hierarchy, which you can provide as a list.

When you import events, you must provide the timestamp in the eventTime field in the format specified by RFC 3339.

Other fields might be required depending on the API method used or if additional fields are used. (For example, if the user event is associated with an entity, make sure to specify the entity field.) For full details of each field and when they are required, see the UserEvent API reference documentation.

JavaScript Pixel

var user_event = {
  "eventType": "category-page-view",
  "visitorId": "visitor-id",
  "pageCategories": ["category1 > category2"]
};

Tag Manager

<script>
    dataLayer = dataLayer || [];
    dataLayer.push({
      'cloud_retail': {
        'eventType': 'category-page-view',
        'visitorId": 'visitor-id',
        // You can also define the user ID and visitor ID
        // directly on the Tag Manager tag.
        'pageCategories': ['category1 > category2']
      }
    });
</script>

BigQuery

This is the complete JSON schema for this user event type. Specify this schema when creating tables for this user event type in BigQuery.

Modes for required fields are set to REQUIRED or REPEATED. Modes for optional fields are set to NULLABLE.

Note that eventTime is required for importing events with BigQuery. eventTime is a string with a Timestamp format.

[
 {
   "name": "eventType",
   "type": "STRING",
   "mode": "REQUIRED"
 },
 {
   "name": "visitorId",
   "type": "STRING",
   "mode": "REQUIRED"
 },
 {
   "name": "eventTime",
   "type": "STRING",
   "mode": "REQUIRED"
 },
 {
   "name": "experimentIds",
   "type": "STRING",
   "mode": "REPEATED"
 },
 {
   "name": "attributionToken",
   "type": "STRING",
   "mode": "NULLABLE"
 },
 {
   "name": "productDetails",
   "type": "RECORD",
   "mode": "REPEATED",
   "fields": [
     {
       "name": "product",
       "type": "RECORD",
       "mode": "REQUIRED",
       "fields": [
         {
           "name": "id",
           "type": "STRING",
           "mode": "REQUIRED"
         }
       ]
     }
   ]
 },
 {
   "name": "pageCategories",
   "type": "STRING",
   "mode": "REPEATED"
 },
 {
   "name": "userInfo",
   "type": "RECORD",
   "mode": "NULLABLE",
   "fields": [
     {
       "name": "userId",
       "type": "STRING",
       "mode": "NULLABLE"
     },
     {
       "name": "ipAddress",
       "type": "STRING",
       "mode": "NULLABLE"
     },
     {
       "name": "userAgent",
       "type": "STRING",
       "mode": "NULLABLE"
     },
     {
       "name": "directUserRequest",
       "type": "BOOLEAN",
       "mode": "NULLABLE"
     }
   ]
 },
 {
   "name": "uri",
   "type": "STRING",
   "mode": "NULLABLE"
 },
 {
   "name": "referrerUri",
   "type": "STRING",
   "mode": "NULLABLE"
 },
 {
   "name": "pageViewId",
   "type": "STRING",
   "mode": "NULLABLE"
 },
 {
   "name": "entity",
   "type": "STRING",
   "mode": "NULLABLE"
 }
]

Detail page view

The following shows the detail-page-view user event data format.

Minimum required detail-page-view object

The following examples show only the required fields of the detail-page-view user event format.

In most cases, productDetails contains details for the associated product, unless a bundle of items are being sold together.

When you import events, you must provide the timestamp in the eventTime field in the format specified by RFC 3339.

Other fields might be required depending on the API method used or if additional fields are used. (For example, if the user event is associated with an entity, make sure to specify the entity field.) For full details of each field and when they are required, see the UserEvent API reference documentation.

JavaScript Pixel

var user_event = {
  "eventType": "detail-page-view",
  "visitorId": "visitor-id",
  "productDetails": [{
    "product": {
      "id": "product-id"
    }
  }]
};

Tag Manager

<script>
    dataLayer = dataLayer || [];
    dataLayer.push({
      'cloud_retail': {
        'eventType': 'detail-page-view',
        'visitorId': 'visitor-id',
        // You can also define the visitor ID directly on
        // the Tag Manager tag.
        'productDetails': [{
          'product': {
            'id': 'product-id'
          }
        }]
      }
    });
</script>

BigQuery

This is the complete JSON schema for this user event type. Specify this schema when creating tables for this user event type in BigQuery.

Modes for required fields are set to REQUIRED or REPEATED. Modes for optional fields are set to NULLABLE.

Note that eventTime is required for importing events with BigQuery. eventTime is a string with a Timestamp format.

[
 {
   "name": "eventType",
   "type": "STRING",
   "mode": "REQUIRED"
 },
 {
   "name": "visitorId",
   "type": "STRING",
   "mode": "REQUIRED"
 },
 {
   "name": "eventTime",
   "type": "STRING",
   "mode": "REQUIRED"
 },
 {
   "name": "experimentIds",
   "type": "STRING",
   "mode": "REPEATED"
 },
 {
   "name": "attributionToken",
   "type": "STRING",
   "mode": "NULLABLE"
 },
 {
   "name": "productDetails",
   "type": "RECORD",
   "mode": "REPEATED",
   "fields": [
     {
       "name": "product",
       "type": "RECORD",
       "mode": "REQUIRED",
       "fields": [
         {
           "name": "id",
           "type": "STRING",
           "mode": "REQUIRED"
         }
       ]
     }
   ]
 },
 {
   "name": "userInfo",
   "type": "RECORD",
   "mode": "NULLABLE",
   "fields": [
     {
       "name": "userId",
       "type": "STRING",
       "mode": "NULLABLE"
     },
     {
       "name": "ipAddress",
       "type": "STRING",
       "mode": "NULLABLE"
     },
     {
       "name": "userAgent",
       "type": "STRING",
       "mode": "NULLABLE"
     },
     {
       "name": "directUserRequest",
       "type": "BOOLEAN",
       "mode": "NULLABLE"
     }
   ]
 },
 {
   "name": "uri",
   "type": "STRING",
   "mode": "NULLABLE"
 },
 {
   "name": "referrerUri",
   "type": "STRING",
   "mode": "NULLABLE"
 },
 {
   "name": "pageViewId",
   "type": "STRING",
   "mode": "NULLABLE"
 },
 {
   "name": "entity",
   "type": "STRING",
   "mode": "NULLABLE"
 }
]

Home page view

The following shows the home-page-view user event format.

Minimum required home-page-view object

The following examples show only the required fields of the home-page-view user event format.

When you import events, you must provide the timestamp in the eventTime field in the format specified by RFC 3339.

Other fields might be required depending on the API method used or if additional fields are used. (For example, if the user event is associated with an entity, make sure to specify the entity field.) For full details of each field and when they are required, see the UserEvent API reference documentation.

JavaScript Pixel

var user_event = {
  "eventType": "home-page-view",
  "visitorId": "visitor-id",
};

Tag Manager

<script>
    dataLayer = dataLayer || [];
    dataLayer.push({
      'cloud_retail': {
        'eventType': 'home-page-view',
        'visitorId': 'visitor-id'
        // You can also define the visitor ID
        // directly on the Tag Manager tag.
      }
    });
</script>

BigQuery

This is the complete JSON schema for this user event type. Specify this schema when creating tables for this user event type in BigQuery.

Modes for required fields are set to REQUIRED or REPEATED. Modes for optional fields are set to NULLABLE.

Note that eventTime is required for importing events with BigQuery. eventTime is a string with a Timestamp format.

[
 {
   "name": "eventType",
   "type": "STRING",
   "mode": "REQUIRED"
 },
 {
   "name": "visitorId",
   "type": "STRING",
   "mode": "REQUIRED"
 },
 {
   "name": "eventTime",
   "type": "STRING",
   "mode": "REQUIRED"
 },
 {
   "name": "experimentIds",
   "type": "STRING",
   "mode": "REPEATED"
 },
 {
   "name": "attributionToken",
   "type": "STRING",
   "mode": "NULLABLE"
 },
 {
   "name": "productDetails",
   "type": "RECORD",
   "mode": "REPEATED",
   "fields": [
     {
       "name": "product",
       "type": "RECORD",
       "mode": "REQUIRED",
       "fields": [
         {
           "name": "id",
           "type": "STRING",
           "mode": "REQUIRED"
         }
       ]
     },
     {
       "name": "quantity",
       "type": "INTEGER",
       "mode": "REQUIRED"
     }
   ]
 },
 {
   "name": "userInfo",
   "type": "RECORD",
   "mode": "NULLABLE",
   "fields": [
     {
       "name": "userId",
       "type": "STRING",
       "mode": "NULLABLE"
     },
     {
       "name": "ipAddress",
       "type": "STRING",
       "mode": "NULLABLE"
     },
     {
       "name": "userAgent",
       "type": "STRING",
       "mode": "NULLABLE"
     },
     {
       "name": "directUserRequest",
       "type": "BOOLEAN",
       "mode": "NULLABLE"
     }
   ]
 },
 {
   "name": "uri",
   "type": "STRING",
   "mode": "NULLABLE"
 },
 {
   "name": "referrerUri",
   "type": "STRING",
   "mode": "NULLABLE"
 },
 {
   "name": "pageViewId",
   "type": "STRING",
   "mode": "NULLABLE"
 },
 {
   "name": "entity",
   "type": "STRING",
   "mode": "NULLABLE"
 }
]

Purchase complete

The following shows the purchase-complete user event data format.

Minimum required purchase-complete object

The following examples show only the required fields of the purchase-complete user event format.

When you import events, you must provide the timestamp in the eventTime field in the format specified by RFC 3339.

Other fields might be required depending on the API method used or if additional fields are used. (For example, if the user event is associated with an entity, make sure to specify the entity field.) For full details of each field and when they are required, see the UserEvent API reference documentation.

JavaScript Pixel

var user_event = {
  "eventType": "purchase-complete",
  "visitorId": "visitor-id",
  "productDetails": [{
    "product": {
      "id": "product-id"
    },
    "quantity": product-quantity
  }],
  "purchaseTransaction": {
    "revenue": revenue,
    "currencyCode": "currency-code"
  }
};

Tag Manager

<script>
    dataLayer = dataLayer || [];
    dataLayer.push({
      'cloud_retail': {
        'eventType': 'purchase-complete',
        'visitorId': 'visitor-id',
        // You can also define the visitor id directly on
        // the Tag Manager tag.
        'productDetails': [{
          'product': {
            'id': 'product-id'
          },
          'quantity': product-quantity
        }],
        'purchaseTransaction': {
          'revenue': revenue,
          'currencyCode': 'currency-code'
        }
      }
    });
</script>

BigQuery

This is the complete JSON schema for this user event type. Specify this schema when creating tables for this user event type in BigQuery.

Modes for required fields are set to REQUIRED or REPEATED. Modes for optional fields are set to NULLABLE.

Note that eventTime is required for importing events with BigQuery. eventTime is a string with a Timestamp format.

[
 {
   "name": "eventType",
   "type": "STRING",
   "mode": "REQUIRED"
 },
 {
   "name": "visitorId",
   "type": "STRING",
   "mode": "REQUIRED"
 },
 {
   "name": "eventTime",
   "type": "STRING",
   "mode": "REQUIRED"
 },
 {
   "name": "experimentIds",
   "type": "STRING",
   "mode": "REPEATED"
 },
 {
   "name": "attributionToken",
   "type": "STRING",
   "mode": "NULLABLE"
 },
 {
   "name": "productDetails",
   "type": "RECORD",
   "mode": "REPEATED",
   "fields": [
     {
       "name": "product",
       "type": "RECORD",
       "mode": "REQUIRED",
       "fields": [
         {
           "name": "id",
           "type": "STRING",
           "mode": "REQUIRED"
         },
         {
           "name": "priceInfo",
           "type": "RECORD",
           "mode": "NULLABLE",
           "fields": [
             {
               "name": "price",
               "type": "FLOAT",
               "mode": "REQUIRED"
             },
             {
               "name": "originalPrice",
               "type": "FLOAT",
               "mode": "NULLABLE"
             },
             {
               "name": "currencyCode",
               "type": "STRING",
               "mode": "REQUIRED"
             },
             {
               "name": "cost",
               "type": "FLOAT",
               "mode": "NULLABLE"
             }
           ]
         }
       ]
     },
     {
       "name": "quantity",
       "type": "INTEGER",
       "mode": "REQUIRED"
     }
   ]
 },
 {
   "name": "cartId",
   "type": "STRING",
   "mode": "NULLABLE"
 },
 {
   "name": "purchaseTransaction",
   "type": "RECORD",
   "mode": "REQUIRED",
   "fields": [
     {
       "name": "id",
       "type": "STRING",
       "mode": "NULLABLE"
     },
     {
       "name": "revenue",
       "type": "FLOAT",
       "mode": "REQUIRED"
     },
     {
       "name": "tax",
       "type": "FLOAT",
       "mode": "NULLABLE"
     },
     {
       "name": "cost",
       "type": "FLOAT",
       "mode": "NULLABLE"
     },
     {
       "name": "currencyCode",
       "type": "STRING",
       "mode": "REQUIRED"
     }
   ]
 },
 {
   "name": "userInfo",
   "type": "RECORD",
   "mode": "NULLABLE",
   "fields": [
     {
       "name": "userId",
       "type": "STRING",
       "mode": "NULLABLE"
     },
     {
       "name": "ipAddress",
       "type": "STRING",
       "mode": "NULLABLE"
     },
     {
       "name": "userAgent",
       "type": "STRING",
       "mode": "NULLABLE"
     },
     {
       "name": "directUserRequest",
       "type": "BOOLEAN",
       "mode": "NULLABLE"
     }
   ]
 },
 {
   "name": "uri",
   "type": "STRING",
   "mode": "NULLABLE"
 },
 {
   "name": "referrerUri",
   "type": "STRING",
   "mode": "NULLABLE"
 },
 {
   "name": "pageViewId",
   "type": "STRING",
   "mode": "NULLABLE"
 },
 {
   "name": "entity",
   "type": "STRING",
   "mode": "NULLABLE"
 }
]

The following shows the search user event format.

Minimum required search object

The following examples show only the required fields of the search user event format.

At least one of searchQuery or pageCategories field is required.

productDetails should include the list of product IDs shown to the end user in the search results page.

When you import events, you must provide the timestamp in the eventTime field in the format specified by RFC 3339.

Other fields might be required depending on the API method used or if additional fields are used. (For example, if the user event is associated with an entity, make sure to specify the entity field.) For full details of each field and when they are required, see the UserEvent API reference documentation.

JavaScript Pixel

var user_event = {
  "eventType": "search",
  "visitorId": "visitor-id",
  "searchQuery": "search-query",
  "pageCategories": ["category1 > category2"],
  "productDetails": [
    {
      "product": {
        "id": "product-id1"
      }
    }, {
      "product": {
        "id": "product-id2"
      }
    }
  ]
};

Tag Manager

<script>
    dataLayer = dataLayer || [];
    dataLayer.push({
      'cloud_retail': {
        'eventType': 'search',
        'visitorId': 'visitor-id',
        // You can also define the visitor ID
        // directly on the Tag Manager tag.
        'searchQuery': 'search-query',
        'pageCategories': ['category1 > category2'],
        'productDetails': [
          {
            'product': {
              'id': 'product-id1'
            }
          }, {
            'product': {
              'id': 'product-id2'
            }
          }
        ]
      }
    });
</script>

BigQuery

This is the complete JSON schema for this user event type. Specify this schema when creating tables for this user event type in BigQuery.

Modes for required fields are set to REQUIRED or REPEATED. Modes for optional fields are set to NULLABLE.

Note that eventTime is required for importing events with BigQuery. eventTime is a string with a Timestamp format.

[
 {
   "name": "eventType",
   "type": "STRING",
   "mode": "REQUIRED"
 },
 {
   "name": "visitorId",
   "type": "STRING",
   "mode": "REQUIRED"
 },
 {
   "name": "eventTime",
   "type": "STRING",
   "mode": "REQUIRED"
 },
 {
   "name": "productDetails",
   "type": "RECORD",
   "mode": "REPEATED",
   "fields": [
     {
       "name": "product",
       "type": "RECORD",
       "mode": "REQUIRED",
       "fields": [
         {
           "name": "id",
           "type": "STRING",
           "mode": "REQUIRED"
         }
       ]
     }
   ]
 },
 {
   "name": "searchQuery",
   "type": "STRING",
   "mode": "NULLABLE"
 },
 {
   "name": "pageCategories",
   "type": "STRING",
   "mode": "REPEATED"
 },
 {
   "name": "entity",
   "type": "STRING",
   "mode": "NULLABLE"
 }
]

Autocomplete

This field is only required for search events if you want to use Autocomplete. It is not required for search.

The following examples show the completionDetail field when a user types "sh" and clicks the second suggestion, "shoes", in the suggestion list to trigger a search event. If the user doesn't click any suggestions, the completionDetail field remains empty.

eventType must be "search".

completionAttributionToken is the attributionToken from completeQuery response.

selectedSuggestion should be the same as searchQuery.

JavaScript Pixel

var user_event = {
  "eventType": "search",
  "visitorId": "visitor-id",
  "searchQuery": "search-query",
  "pageCategories": ["category1 > category2"],
  "productDetails": [
    {
      "product": {
        "id": "product-id1"
      }
    }, {
      "product": {
        "id": "product-id2"
      }
    }
  ]
  "completionDetail": {
    "completionAttributionToken": "completion_token",
    "selectedSuggestion": "search-query",
    "selectedPosition": completion_position
  }
};

Tag Manager

<script>
    dataLayer = dataLayer || [];
    dataLayer.push({
      'cloud_retail': {
        'eventType': 'search',
        'visitorId': 'visitor-id',
        // You can also define the visitor ID
        // directly on the Tag Manager tag.
        'searchQuery': 'search-query',
        'pageCategories': ['category1 > category2'],
        'productDetails': [
          {
            'product': {
              'id': 'product-id1'
            }
          }, {
            'product': {
              'id': 'product-id2'
            }
          }
        ]
        "completionDetail": {
          "completionAttributionToken": 'completion_token',
          "selectedSuggestion": 'search-query',
          "selectedPosition": completion_position
        }
      }
    });
</script>

BigQuery

This is the complete JSON schema for this user event type. Specify this schema when creating tables for this user event type in BigQuery.

Modes for required fields are set to REQUIRED or REPEATED. Modes for optional fields are set to NULLABLE.

Note that eventTime is required for importing events with BigQuery. eventTime is a string with a Timestamp format.

[
 {
   "name": "eventType",
   "type": "STRING",
   "mode": "REQUIRED"
 },
 {
   "name": "visitorId",
   "type": "STRING",
   "mode": "REQUIRED"
 },
 {
   "name": "eventTime",
   "type": "STRING",
   "mode": "REQUIRED"
 },
 {
   "name": "productDetails",
   "type": "RECORD",
   "mode": "REPEATED",
   "fields": [
     {
       "name": "product",
       "type": "RECORD",
       "mode": "REQUIRED",
       "fields": [
         {
           "name": "id",
           "type": "STRING",
           "mode": "REQUIRED"
         }
       ]
     }
   ]
 },
 {
   "name": "searchQuery",
   "type": "STRING",
   "mode": "NULLABLE"
 },
 {
   "name": "pageCategories",
   "type": "STRING",
   "mode": "REPEATED"
 },
 {
   "name": "completionDetail",
   "type": "RECORD"
   "mode": "NULLABLE"
   "fields": [
     {
       "name": "completionAttributionToken",
       "type": "STRING",
       "mode": "REQUIRED"
     },
     {
       "name": "selectedSuggestion",
       "type": "STRING",
       "mode": "REQUIRED"
     },
     {
       "name": "selectedPosition",
       "type": "INTEGER",
       "mode": "REQUIRED"
     }
    ]
 }
]

Shopping cart page view

The following shows the shopping-cart-page-view user event data format.

Minimum required shopping-cart-page-view object

The following examples show only the required fields of the shopping-cart-page-view user event format.

Provide the productDetails object unless the shopping cart is empty.

When you import events, you must provide the timestamp in the eventTime field in the format specified by RFC 3339.

Other fields might be required depending on the API method used or if additional fields are used. (For example, if the user event is associated with an entity, make sure to specify the entity field.) For full details of each field and when they are required, see the UserEvent API reference documentation.

JavaScript Pixel

var user_event = {
  "eventType": "shopping-cart-page-view",
  "visitorId": "visitor-id
  "cartId": "cart-id",
  "productDetails": [{
    "product": {
       "id": "product-id"
     },
     {
       "id": "product-id"
     }
   }]
};

Tag Manager

<script>
    dataLayer = dataLayer || [];
    dataLayer.push({
      'cloud_retail': {
        'eventType': 'shopping-cart-page-view',
        'visitorId': 'visitor-id'
        // You can also define the visitor ID
        // directly on the Tag Manager tag.
        'cartId': 'cart-id',
        'productDetails': [{
          'product': {
            'id': 'product-id'
           },
           {
             'id': 'product-id'
           }
         }]
      }
    });
</script>

BigQuery

This is the complete JSON schema for this user event type. Specify this schema when creating tables for this user event type in BigQuery.

Modes for required fields are set to REQUIRED or REPEATED. Modes for optional fields are set to NULLABLE.

Note that eventTime is required for importing events with BigQuery. eventTime is a string with a Timestamp format.

[
 {
   "name": "eventType",
   "type": "STRING",
   "mode": "REQUIRED"
 },
 {
   "name": "visitorId",
   "type": "STRING",
   "mode": "REQUIRED"
 },
 {
   "name": "eventTime",
   "type": "STRING",
   "mode": "REQUIRED"
 },
 {
   "name": "experimentIds",
   "type": "STRING",
   "mode": "REPEATED"
 },
 {
   "name": "attributionToken",
   "type": "STRING",
   "mode": "NULLABLE"
 },
 {
   "name": "productDetails",
   "type": "RECORD",
   "mode": "REPEATED",
   "fields": [
     {
       "name": "product",
       "type": "RECORD",
       "mode": "REQUIRED",
       "fields": [
         {
           "name": "id",
           "type": "STRING",
           "mode": "REQUIRED"
         }
       ]
     },
     {
       "name": "quantity",
       "type": "INTEGER",
       "mode": "REQUIRED"
     }
   ]
 },
 {
   "name": "cartId",
   "type": "STRING",
   "mode": "NULLABLE"
 },
 {
   "name": "userInfo",
   "type": "RECORD",
   "mode": "NULLABLE",
   "fields": [
     {
       "name": "userId",
       "type": "STRING",
       "mode": "NULLABLE"
     },
     {
       "name": "ipAddress",
       "type": "STRING",
       "mode": "NULLABLE"
     },
     {
       "name": "userAgent",
       "type": "STRING",
       "mode": "NULLABLE"
     },
     {
       "name": "directUserRequest",
       "type": "BOOLEAN",
       "mode": "NULLABLE"
     }
   ]
 },
 {
   "name": "uri",
   "type": "STRING",
   "mode": "NULLABLE"
 },
 {
   "name": "referrerUri",
   "type": "STRING",
   "mode": "NULLABLE"
 },
 {
   "name": "pageViewId",
   "type": "STRING",
   "mode": "NULLABLE"
 },
 {
   "name": "entity",
   "type": "STRING",
   "mode": "NULLABLE"
 }
]

Google Analytics 4 user event fields

The following table shows how Google Analytics 4 user event fields map to Retail fields.

Before you import or record user events from Google Analytics 4, make sure your Google Analytics 4 user events use the following fields so that Retail can integrate your data correctly.

Google Analytics 4 Retail
ecommerce.purchase_revenue purchaseTransaction.revenue
event_name eventType
event_timestamp eventTime
items.item_id productDetails.product.id
items.price productDetails.product.priceInfo.price
items.quantity productDetails.quantity
Key:
event_params.key set to "currency"

Value:
event_params.value.string_value
productDetails.product.priceInfo.currencyCode
Key:
event_params.key set to "currency"

Value:
event_params.value.string_value
purchaseTransaction.currencyCode
Key:
event_params.key set to "search_term"

Value:
event_params.value.string_value
searchQuery
user_id userInfo.userId
user_pseudo_id visitorId

Custom attributes

You can include additional custom attributes and features for user events. This can result in improved, more specific recommendations for your users when you use Recommendations. To add custom attributes, use attributes when you record a user event.

If you provide custom attributes for ingested user events, it's important to also include them in the user events that you associate with prediction requests. The formatting of custom attributes must be consistent between imported events and events provided with prediction requests. This lets the Retail API use those custom attributes when training models and serving predictions, which helps improve recommendation quality.

You can provide custom text values by using the text field, or custom numerical values by using the number field.

For example, the following shows the attributes section from a request to record a user event:

"attributes": {
  "user_age": {"text": ["teen", "young adult"]},
  "user_location": {"text": ["CA"]}
}

About user information

visitorId represents the unique user identifier and is required when you record a user event.

The user information (UserInfo) included when you record a user event contains the visitorId value and, if available, the userId value. userId is optional and can be used as a unique, persistent identifier for a user across devices whenever a user logs in to your site. When you record the userId for a user, the Retail API can generate more personalized results for one user across multiple devices, such as both a mobile device and a web browser.

About the timestamp

When you record a user event, be sure to include an accurate timestamp of when the event occurred. Accurate timestamps ensure that the Retail API stores events in the correct order. Timestamps are recorded automatically for events collected using Tag Manager and the JavaScript Pixel. When you import events, you must provide the timestamp in the eventTime field in the format specified by RFC 3339.

What's next