Для сбора статистики и последующей оптимизации кампаний необходимо передавать информацию о взаимодействиях пользователя с контентом и товарами.

---

## engagement: передача взаимодействий пользователя с кампаниями

!!!contrast API reference
[:icon-terminal: GET /engagement](https://openapi-v2.gravityfield.ai/engagement-14151113e0)
!!!

В API V2 tracking URL рекомендуется брать из ответа `/choose`. Для этого передайте `options.isBuildEngagementUrl: true`.

Когда эта опция включена, Gateway добавляет готовые URL в response. Клиенту не нужно самостоятельно собирать `eventId`, `slotId`, `decisionId` и другие параметры tracking-запроса.

=== Пример включения генерации URL в `/choose`:
```json
{
  "options": {
    "isBuildEngagementUrl": true
  }
}
```
===

=== Пример вызова tracking URL:
```jsx
curl --request GET 
--url 'https://evs-01.gravityfield.ai/v2/engagement?eventId=EVENT_ID&type=WRIMP&sec=YOUR_SECTION_ID'
```
===

### Где брать URL

В ответе `/choose` есть два уровня tracking:

- `content.events[].urls[]` - tracking для всего контентного блока;
- `products.slots[].events[].urls[]` - tracking для отдельных товарных карточек.

Content-level события обычно связаны с action-ами из `variables`:

```json
{
  "variables": {
    "onImpression": {
      "action": "IMP"
    },
    "onVisibleImpression": {
      "action": "WRIMP"
    }
  },
  "events": [
    {
      "type": "IMP",
      "urls": ["https://evs-01.gravityfield.ai/v2/engagement?..."]
    },
    {
      "type": "WRIMP",
      "urls": ["https://evs-01.gravityfield.ai/v2/engagement?..."]
    }
  ]
}
```

Принцип работы:

1. UI получает `action` из `variables.onLoad`, `variables.onImpression`, `variables.onVisibleImpression`, `variables.onClose` или `element.onClick`.
2. Клиент ищет событие с таким же значением в `content.events[].type`.
3. Клиент вызывает все URL из найденного `events[].urls[]`.

Для товарных карточек источник событий другой:

```json
{
  "slotId": "665f0f000000000000000001:1",
  "item": {
    "sku": "sku-456"
  },
  "events": [
    {
      "type": "visible_impression",
      "urls": ["https://evs-01.gravityfield.ai/v2/engagement?..."]
    },
    {
      "type": "click",
      "urls": ["https://evs-01.gravityfield.ai/v2/engagement?..."]
    }
  ]
}
```

!!!
Для товарных рекомендаций не заменяйте `products.slots[].events[]` на content-level tracking. Иначе статистика по конкретным товарам будет неполной.
!!!

### Когда отправлять

| Что отправлять | Когда |
| :--- | :--- |
| `onLoad` | После успешной загрузки контента. |
| `onImpression` | После первого фактического рендера блока. |
| `onVisibleImpression` | Один раз, когда блок стал видим пользователю. |
| `onClose` | Когда пользователь закрыл in-app блок. |
| `slot.visible_impression` | Один раз, когда карточка товара стала видимой. |
| `slot.click` | Когда пользователь нажал на карточку товара. |

Для visible impression используйте ту же модель, что и SDK: отправляйте событие один раз, когда элемент достиг как минимум `50%` видимости.

### Как отправлять URL

Tracking URL вызывается `GET`-запросом. Ответ tracking-запроса не нужно использовать для рендера UI.

Рекомендации:

- отправляйте все URL из подходящего `urls[]`;
- не блокируйте UI из-за ошибки tracking-запроса;
- не повторяйте `impression` и `visible_impression` при каждом повторном render cycle;
- при клике сначала отправьте tracking URL, затем выполните действие интерфейса, если это не ухудшает UX.

### Если URL не пришли

Если в ответе `/choose` нет tracking URL, проверьте:

- передан ли `options.isBuildEngagementUrl: true`;
- используется ли актуальный ответ `/choose`, а не преобразованная на вашей стороне модель без `events`;
- сохраняются ли `content.events[]` и `products.slots[].events[]` при передаче данных в UI-слой.
