# 3. Events

Events are required to track important user actions such as adding an item to the cart or to the wishlist, logging into a personal account, and many more. Tracking these events is necessary to understand user behavior for specific targeting, as well as for the proper functioning of recommendation strategies. To send data to Gravity Field, you need to embed a small code for each required event.

In the event, you can pass a set of parameters that you plan to use for future work. Some events, such as `Purchase` or `Login`, require implementation according to a certain scheme. However, for other target actions, you can create and personalize your own events.

{% hint style="info" %}
**Important:** for e-commerce implementation, `Purchase` and `Add to Cart` events are mandatory, but we also recommend implementing the maximum number of events from the pre-configured list that are relevant to your site. This will aid in implementing  more use cases and expand the user's profile. The final list of required events is agreed with the team working on your project and depends on the planned use cases.
{% endhint %}

## **Pre-configured events**

### Add to Cart (mandatory for e-commerce)

Example:

{% tabs %}
{% tab title="Javascript" %}

<pre class="language-javascript"><code class="lang-javascript"><strong>GF.API("event", {
</strong>  name: "Add to Cart",
  properties: {
    eventType: "add-to-cart-v1",
    value: 118.26,
    currency: "USD", //any supported currency code
    productId: "item-34454",
    quantity: 2,
    cart: [{
        productId: "sku-4324-bg",
        quantity: 2,
        itemPrice: 12.34,
      },
      {
        productId: "item-34454",
        quantity: 2,
        itemPrice: 59.13
      }
    ]
  }
});
</code></pre>

{% endtab %}
{% endtabs %}

**properties** container definition:

| Property                                            | Description                                                                                                                                                          | Type              |
| --------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------- |
| **eventType**<mark style="color:red;">**\***</mark> | Must be "`add-to-cart-v1`"                                                                                                                                           | string            |
| **value**<mark style="color:red;">**\***</mark>     | The value added to the cart. If more than one item is added, contains the unit price multiplied by the quantity. For example, for  99 dollars 99 cents it's  `99.99` | float             |
| **currency**                                        | The currency used for the value (Supported standard - ISO 4217, letter code, for example, "`USD`"). Optional but required for multi-currency sites                   | string            |
| **productId**<mark style="color:red;">**\***</mark> | SKU as in the feed                                                                                                                                                   | string            |
| **quantity**<mark style="color:red;">**\***</mark>  | The number of items added to the cart                                                                                                                                | integer, positive |
| **cart**                                            | The current state of the cart, including the last item added. Items must be listed in the order they were added, from oldest to newest                               | array             |
| Product in cart object:                             |                                                                                                                                                                      |                   |
| **productId**<mark style="color:red;">**\***</mark> | SKU as in the feed                                                                                                                                                   | string            |
| **quantity**<mark style="color:red;">**\***</mark>  | The number of units of this item in the cart                                                                                                                         | integer, positive |
| **itemPrice**<mark style="color:red;">**\***</mark> | The price of one item after discounts (if any)                                                                                                                       | float             |

{% hint style="warning" %}
Common mistakes:

In the Add to Cart event, the `quantity` parameter is often passed incorrectly. This parameter should reflect the actual number of items added to the cart, not the sum of all units after the action. Example: there were 2 items of a specific SKU in the cart, and we added 1 more item of the same SKU. In the event, we expect to see `quantity=1`.
{% endhint %}

### Purchase (mandatory for e-commerce)

Example:

{% tabs %}
{% tab title="Javascript" %}

```javascript
GF.API("event", {
  name: "Purchase",
  properties: {
    uniqueTransactionId: "123456",
    eventType: "purchase-v1",
    value: 90.55,
    currency: "USD", //any supported currency code
    cart: [
      {
        productId: "item-34454",
        quantity: 1,
        itemPrice: 65.87,
      }, {
        productId: "sku-4324-bg",
        quantity: 2,
        itemPrice: 12.34,
      }
    ]
  }
});
```

{% endtab %}
{% endtabs %}

**properties** container definition:

| Property                                            | Description                                                                                                                                        | Type              |
| --------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------- |
| **eventType**<mark style="color:red;">**\***</mark> | Must be "`purchase-v1`"                                                                                                                            | string            |
| **uniqueTransactionId**                             | Unique transaction ID. Helps to deduplicate transaction events. Maximum 64 characters                                                              | string            |
| **value**<mark style="color:red;">**\***</mark>     | Monetary value of the event. For example, 99 dollars 99 cents is `99.99`                                                                           | float             |
| **currency**                                        | The currency used for the value (Supported standard - ISO 4217, letter code, for example, "`USD`"). Optional but required for multi-currency sites | string            |
| **cart**<mark style="color:red;">**\***</mark>      | Products must be listed in the order they were added - from the oldest to the newest                                                               |                   |
| Product in cart object:                             |                                                                                                                                                    |                   |
| **productId**<mark style="color:red;">**\***</mark> | SKU, same as in the feed                                                                                                                           | string            |
| **quantity**<mark style="color:red;">**\***</mark>  | Amount of units of this product in the cart                                                                                                        | integer, positive |
| **itemPrice**<mark style="color:red;">**\***</mark> | Cost of one unit of the product after discounts (if any) have been applied                                                                         | float             |

### Remove From Cart

Example:

{% tabs %}
{% tab title="Javascript" %}

```javascript
GF.API("event", {
  name: "Remove from Cart",
  properties: {
    eventType: "remove-from-cart-v1",
    value: 34.45,
    currency: "USD", //any supported currency code
    productId: "gswefd-34-454",
    quantity: 1,
    cart: [{
        productId: "sku-4324-bg",
        quantity: 2,
        itemPrice: 12.34,
      },
      {
        productId: "item-34454",
        quantity: 1,
        itemPrice: 34.45
      }
    ]
  }
});
```

{% endtab %}
{% endtabs %}

**properties** container definition:

| Property                                            | Description                                                                                                                                                                                                           | Type              |
| --------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------- |
| **eventType**<mark style="color:red;">**\***</mark> | Must be "`remove-from-cart-v1`"                                                                                                                                                                                       | string            |
| **value**<mark style="color:red;">**\***</mark>     | Cost of the removed item(s). If more than one unit of an item is removed, this should contain the total cost. If multiple SKUs are removed at once, it is recommended to use [#sync-cart](#sync-cart "mention") event | float             |
| **currency**                                        | The currency used for the value (Supported standard - ISO 4217, letter code, for example, "`USD`"). Optional but required for multi-currency sites                                                                    | string            |
| **productId**<mark style="color:red;">**\***</mark> | SKU, same as in the feed                                                                                                                                                                                              | string            |
| **quantity**<mark style="color:red;">**\***</mark>  | Number of units of this product removed from the cart                                                                                                                                                                 | integer, positive |
| **cart**                                            | Current state of the cart, excluding the removed item. Products must be listed in the order they were added - from oldest to newest                                                                                   | array             |
| Product in cart object:                             |                                                                                                                                                                                                                       |                   |
| **productId**<mark style="color:red;">**\***</mark> | SKU, same as in the feed                                                                                                                                                                                              | string            |
| **quantity**<mark style="color:red;">**\***</mark>  | Number of units of this product in the cart                                                                                                                                                                           | integer, positive |
| **itemPrice**<mark style="color:red;">**\***</mark> | Cost of one unit of the product after discounts (if any) have been applied                                                                                                                                            | float             |

### Sync cart

This event updates the current state of the cart. This event is recommended in the case of bulk changes in the cart or changes to the cart contents without user involvement, for example:

1. Server-side cart update (e.g., items that ran out of stock during the user's session automatically removed from the cart)
2. Cart update upon user authorization (combining carts before/after login)
3. Cart update upon entering the site, including auto-login (e.g., automatic loading of a mobile cart when entering the web platform)
4. Mass removal of items from the cart - complete cart clearing or removal of a number of positions with one click

Example:

{% tabs %}
{% tab title="Javascript" %}

```javascript
GF.API("event", {
  name: "Sync cart",
  properties: {
    eventType: "sync-cart-v1",
    currency: "USD", //any supported currency code
    cart: [ 
      {
        productId: "sku-4324-bg",
        quantity: 2,
        itemPrice: 12.34,
      },
      {
        productId: "item-34454",
        quantity: 1,
        itemPrice: 34.45
      }
    ]
  }
});
```

{% endtab %}
{% endtabs %}

**properties** container definition:

| Property                                            | Description                                                                                                                                                  | Type              |
| --------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------- |
| **eventType**<mark style="color:red;">**\***</mark> | Must be "`sync-cart-v1`"                                                                                                                                     | string            |
| **currency**                                        | The currency used for the value (Supported standard - ISO 4217, letter code, for example, "`USD`"). Optional but required for multi-currency sites           | string            |
| **cart**<mark style="color:red;">**\***</mark>      | Current state of the cart, excluding the removed item/including the added item. Products must be listed in the order they were added - from oldest to newest | array             |
| Product in cart object:                             |                                                                                                                                                              |                   |
| **productId**<mark style="color:red;">**\***</mark> | SKU, same as in the feed                                                                                                                                     | string            |
| **quantity**<mark style="color:red;">**\***</mark>  | Number of units of this product in the cart                                                                                                                  | integer, positive |
| **itemPrice**<mark style="color:red;">**\***</mark> | Cost of one unit of the product after discounts (if any) have been applied                                                                                   | float             |

### Adding to Wishlist/Favourites

Example:

{% tabs %}
{% tab title="Javascript" %}

```javascript
GF.API("event", {
  name: "Add to Wishlist",
  properties: {
    eventType: "add-to-wishlist-v1",
    productId: "item-34454"
  }
});
```

{% endtab %}
{% endtabs %}

**properties** container definition:

| Property                                            | Description                    | Type   |
| --------------------------------------------------- | ------------------------------ | ------ |
| **eventType**<mark style="color:red;">**\***</mark> | Must be "`add-to-wishlist-v1`" | string |
| **productId**<mark style="color:red;">**\***</mark> | SKU, same as in the feed       | string |

### Attribute Change

Used when the user changes the attribute of the displayed product, such as size or color.

Example:

{% tabs %}
{% tab title="Javascript" %}

```jsx
GF.API("event", {
  name: "Change Attribute",
  properties: {
    eventType: "change-attr-v1",
    attributeType: "Color",
    attributeValue: "Navy Blue"
  }
});
```

{% endtab %}
{% endtabs %}

**properties** container definition:

| Property                                                 | Description                                                        | Type   |
| -------------------------------------------------------- | ------------------------------------------------------------------ | ------ |
| **eventType**<mark style="color:red;">**\***</mark>      | Must be "`change-attr-v1`"                                         | string |
| **attributeType**<mark style="color:red;">**\***</mark>  | Color, size, brand, etc., must match the column header in the feed | string |
| **attributeValue**<mark style="color:red;">**\***</mark> | New value, must match the values in the feed                       | string |

{% hint style="info" %}
The attribute type and value must match the values in the feed.
{% endhint %}

### Product Filtering

Used when the user filters products by a field value (usually in a PLP).

Example:

{% tabs %}
{% tab title="Javascript" %}

```javascript
GF.API("event", {
  name: "Filter Items",
  properties: {
    eventType: "filter-items-v1",
    filterType: "Color", // Name of filter (Color, Size, Brand, Fit, Author, Keyword, Category...)
    filterNumericValue: 4
  }
});
```

{% endtab %}
{% endtabs %}

**properties** container definition:

| Property                                                      | Description                                                                                                                            | Type   |
| ------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- | ------ |
| **eventType**<mark style="color:red;">**\***</mark>           | Must be "`filter-items-v1`"                                                                                                            | string |
| **filterType**<mark style="color:red;">**\***</mark>          | Filter name (color, size, brand, etc.). Must match the item property specified in the feed                                             | string |
| **filterNumericValue**<mark style="color:red;">**\***</mark>  | Only one value is accepted: filterNumericValue OR filterStringValue, but not both. This affects the available segmentation conditions. | number |
| **filterStringValue**<mark style="color:red;">**\*\***</mark> | Only one value is accepted: filterNumericValue OR filterStringValue, but not both. This affects the available segmentation conditions. | string |

### Keyword Search

Example:

{% tabs %}
{% tab title="Javascript" %}

```javascript
GF.API("event", {
  name: "Keyword Search",
  properties: {
    eventType: "keyword-search-v1",
    keywords: "my search string"
  }
});
```

{% endtab %}
{% endtabs %}

**properties** container definition:

| Property                                            | Description                         | Type   |
| --------------------------------------------------- | ----------------------------------- | ------ |
| **eventType**<mark style="color:red;">**\***</mark> | Must be "`keyword-search-v1`"       | string |
| **keywords**<mark style="color:red;">**\***</mark>  | Search query as entered by the user | string |

**Aggregating Requests for Live Search**

In cases when live search is available on the site (also called search-as-you-type), it is necessary to perform query aggregation when sending events. When using this method, we don’t pass every entered character in a separate event, and only the last input state is sent to the system. For example, when a user enters the query "game", four entries are created: "g", "ga", "gam", and finally, "game". However, only the last input "game" is sent to the system, ignoring the previous ones.

{% hint style="info" %}
When sending the event, it is necessary to indicate a delay after which the request will be sent to the system. For example, if a user starts entering "gam", stops, and 2 seconds have passed (recommended as maximum delay), the request "gam" should be sent to the system. Next, if the user decides to continue inputting, adds "game", and stops, after 2 seconds, the second input result "game" should be sent. It is recommended to sync the sending of the event with the search query rendering for the user, or when the user hits "Enter" or clicks on "Search".
{% endhint %}

### Promo Code Entry

Example:

{% tabs %}
{% tab title="Javascript" %}

```javascript
GF.API("event", {
  name: "Promo Code Entered",
  properties: {
    eventType: "enter-promo-code-v1",
    code: "..."
  }
});
```

{% endtab %}
{% endtabs %}

**properties** container definition:

| Property                                            | Description                     | Type   |
| --------------------------------------------------- | ------------------------------- | ------ |
| **eventType**<mark style="color:red;">**\***</mark> | Must be "`enter-promo-code-v1`" | string |
| **code**<mark style="color:red;">**\***</mark>      | Promo code                      | string |

### Sort Items

Example:

{% tabs %}
{% tab title="Javascript" %}

<pre class="language-javascript"><code class="lang-javascript"><strong>GF.API("event", {
</strong>  name: "Sort Items",
  properties: {
    eventType: "sort-items-v1",
    sortBy: "price",
    sortOrder: "ASC"
  }
});
</code></pre>

{% endtab %}
{% endtabs %}

**properties** container definition:

| Property                                            | Description                                                                                                                                                                              | Type   |
| --------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------ |
| **eventType**<mark style="color:red;">**\***</mark> | Must be "`sort-items-v1`"                                                                                                                                                                | string |
| **sortBy**<mark style="color:red;">**\***</mark>    | Any of the parameters: price, term, popularity, rating, and more. The parameter must match the name of a column in the feed (if there are matching columns) or be a human-readable value | string |
| **sortOrder**<mark style="color:red;">**\***</mark> | Ascending or descending (ASC or DESC)                                                                                                                                                    | string |

### Newsletter Subscription

Example:

{% tabs %}
{% tab title="Javascript" %}

```javascript
GF.API("event", {
  name: "Subscription",
  properties: {
    eventType: "newsletter-subscription-v1",
    hashedEmail: "SHA-256 hash of the email",   }
});
// and/or
GF.API("event", {
  name: "Subscription",
  properties: {
    eventType: "newsletter-subscription-v1",
    cuid: "...", 
    cuidType: "..." 
  }
});
```

{% endtab %}
{% endtabs %}

**properties** container definition:

| Property                                              | Description                                                                    | Type   |
| ----------------------------------------------------- | ------------------------------------------------------------------------------ | ------ |
| **eventType**<mark style="color:red;">**\***</mark>   | Must be "`newsletter-subscription-v1`"                                         | string |
| **hashedEmail**<mark style="color:red;">**\***</mark> | Email, converted to lowercase and hashed on the client side in SHA-256 format  | string |
| **cuid**<mark style="color:red;">**\*\***</mark>      | If identification is not by email, any other customer ID is passed (optional)  | string |
| **cuidType**<mark style="color:red;">**\***</mark>    | When passing cuid, its type is passed (required when passing the "cuid" field) | string |

`cuid` can represent any internal identifier, such as CRM ID, mobile phone hash, and others.

{% hint style="warning" %}
We strongly recommend to hash any identifiers containing personal data.
{% endhint %}

### Signup

Example:

{% tabs %}
{% tab title="Javascript" %}

```javascript
GF.API("event", {
  name: "Signup",
  properties: {
    eventType: "signup-v1",
    hashedEmail: "SHA-256 hash of the email",   }
});
// or/and
GF.API("event", {
  name: "Signup",
  properties: {
    eventType: "signup-v1",
    cuid: "...", 
    cuidType: "..." 
  }
});
```

{% endtab %}
{% endtabs %}

**properties** container definition:

| Property                                              | Description                                                                    | Type   |
| ----------------------------------------------------- | ------------------------------------------------------------------------------ | ------ |
| **eventType**<mark style="color:red;">**\***</mark>   | Must be "`signup-v1`"                                                          | string |
| **hashedEmail**<mark style="color:red;">**\***</mark> | Email, converted to lowercase and hashed on the client side in SHA-256 format  | string |
| **cuid**<mark style="color:red;">**\*\***</mark>      | If identification is not by email, any other customer ID is passed (optional)  | string |
| **cuidType**<mark style="color:red;">**\***</mark>    | When passing cuid, its type is passed (required when passing the "cuid" field) | string |

`cuid` can represent any internal identifier, such as CRM ID, mobile phone hash, and others.

{% hint style="warning" %}
We strongly recommend to hash any identifiers containing personal data.
{% endhint %}

### Login

Example:

{% tabs %}
{% tab title="Javascript" %}

```javascript
GF.API("event", {
  name: "Login",
  properties: {
    eventType: "login-v1",
    hashedEmail: "SHA-256 hash of the email"
	}
});
// or/and
GF.API("event", {
  name: "Login",
  properties: {
    eventType: "login-v1",
    cuid: "...", 
    cuidType: "..." 
  }
});
```

{% endtab %}
{% endtabs %}

**properties** container definition:

| Property                                              | Description                                                                    | Тип    |
| ----------------------------------------------------- | ------------------------------------------------------------------------------ | ------ |
| **eventType**<mark style="color:red;">**\***</mark>   | Must be "`login-v1`"                                                           | string |
| **hashedEmail**<mark style="color:red;">**\***</mark> | Email, converted to lowercase and hashed on the client side in SHA-256 format  | string |
| **cuid**<mark style="color:red;">**\*\***</mark>      | If identification is not by email, any other customer ID is passed (optional)  | string |
| **cuidType**<mark style="color:red;">**\***</mark>    | When passing cuid, its type is passed (required when passing the "cuid" field) | string |

`cuid` can represent any internal identifier, such as CRM ID, mobile phone hash, and others.

{% hint style="warning" %}
We strongly recommend to hash any identifiers containing personal data.
{% endhint %}

### User Identification

There are two globally accepted types of user identifiers:

1. Hashed email of the user, i.e., the encrypted email address or phone number of the user.  **hashedEmail**.&#x20;
   1. If passing an email, turn it to lowercase, then hash.\
      Example:

      <Test@TEST.com> → <test@test.com> - convert to lowercase

      <test@test.com> → `f660ab912ec121d1b1e928a0bb4bc61b15f5ad44d5efdc4e1c92a25e99b8e44a` - SHA256 hash
   2. If passing phone number, then format

      971XXXXXXXXXX (start with country code, e.g. 971, without "+", dashes, and brackets), then hash.
2. **Cuid** - Customer Unique Identifier. Cuid can be any unique value used to identify a user - it can be a phone number, CRM ID, or any other ID.

{% hint style="warning" %}
We strongly recommend to hash any identifiers containing personal data.
{% endhint %}

## Custom Event

If you want to track an event not listed above, the following structure can be used to design it:&#x20;

```javascript
GF.API("event", {
  name: "EVENT_NAME",
  properties: {  
    FIRST PROPERTY NAME: "PROPERTY VALUE",  // Optional, string
    SECOND PROPERTY NAME: "PROPERTY VALUE",  // Optional, string
    value: 199.99 // Optional, float
  }
})
```
