Перейти к основному содержимому

Визиты и корзина

Трекинг даёт платформе поведение посетителя: какие страницы он смотрел, что положил в корзину и когда. На этом строятся сегменты вроде «смотрел раздел, но не купил» и сценарии брошенной корзины.

Готовый трекер для сайта

Визиты и цели с сайта не обязательно отправлять самим: есть JS-трекер и пример приёмника к нему. Методы на этой странице нужны, если вы отправляете события со своего сервера или из приложения.

Особенность трекинга в том, что события происходят до того, как посетитель стал известным клиентом. Поэтому все методы работают с идентификатором сессии, а клиент подставляется позже.


Идентификатор сессии

SESSID — ваша строка, которая одинакова для всех событий одного посетителя в рамках его сессии. Платформа не проверяет её формат, но от неё зависит, соберутся ли события в одну цепочку.

Требования и особенности:

  • значение должно жить столько же, сколько сессия посетителя, и не меняться от страницы к странице;
  • у разных посетителей значения должны различаться — подойдёт идентификатор серверной сессии или случайный токен в cookie;
  • не используйте идентификатор клиента как SESSID: тогда события неавторизованных посетителей склеятся.

Как только посетитель опознан (вошёл в аккаунт, перешёл по ссылке из письма), вызывайте связывание сессии с клиентом — и все события этой сессии, включая уже записанные, привяжутся к карточке.


Визит страницы

POST /tracking/pageview
{
"SESSID": "a1b2c3d4e5f60718",
"USER_ID": "1042",
"PAGE_URL": "https://example.ru/catalog/kurtki/?sort=price",
"DOMAIN": "example.ru",
"PAGE_PATH": "/catalog/kurtki/",
"PROTOCOL": "https",
"DATETIME": "2026-09-18 10:14:55",
"REFERRER": "https://yandex.ru/search/?text=куртки",
"IP_ADDRESS": "203.0.113.24",
"USER_AGENT": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_5 like Mac OS X) AppleWebKit/605.1.15",
"QUERY_PARAMS": {
"sort": "price",
"utm_source": "yandex",
"utm_campaign": "autumn"
}
}
ПолеОбязательноОписание
SESSIDдаИдентификатор сессии посетителя
PAGE_URLдаПолный адрес страницы, до 2048 символов
DOMAINдаДомен без схемы
PAGE_PATHдаПуть без домена и параметров
USER_IDнетВаш идентификатор клиента, если посетитель опознан. Заодно выполняет связывание сессии
PROTOCOLнетhttps или http. По умолчанию https
DATETIMEнетВремя визита. По умолчанию — время приёма запроса
REFERRERнетИсточник перехода, до 2048 символов
IP_ADDRESSнетIP-адрес посетителя
USER_AGENTнетСтрока браузера, до 1024 символов. Платформа разбирает её на устройство и браузер
QUERY_PARAMSнетПараметры адреса объектом «имя: значение». Сюда попадают UTM-метки

Требования и особенности:

  • визиты отправляйте со своего сервера, а не из браузера: в браузере ключ коннектора станет публичным;
  • UTM-метки передавайте в QUERY_PARAMS — по ним считается статистика источников;
  • сервер не проверяет, не отправляли ли вы эту же страницу секунду назад: отсекайте повторные визиты одной страницы на своей стороне;
  • ответ приходит сразу, запись выполняется после ответа. success: true означает «визит принят», а не «визит уже в базе».
{ "success": true, "code": 200, "message": "Визит принят" }

Связывание сессии с клиентом

Вызывается в момент, когда анонимный посетитель стал известным: вошёл в аккаунт, оформил заказ, перешёл по ссылке из письма.

POST /tracking/bind-user
{
"SESSID": "a1b2c3d4e5f60718",
"USER_ID": "1042"
}
ПолеОбязательноОписание
SESSIDдаИдентификатор сессии посетителя
USER_IDдаВаш идентификатор клиента

Платформа находит клиента по вашему USER_ID и привязывает к нему все события этой сессии — и прошлые, и будущие.

{
"success": true,
"code": 200,
"message": "Записи трекинга привязаны к пользователю",
"data": { "client_user_id": 1042, "instance_user_id": 317, "updated_sessid": "a1b2c3d4e5f60718" }
}

Если клиент с таким идентификатором ещё не передавался, привязки не происходит. Обратите внимание: ответ при этом успешный"success": true, — а признак проблемы в полях code и error:

{
"success": true,
"code": 404,
"error": "Пользователь с XML_ID=1042 не найден",
"data": { "client_user_id": "1042" }
}

Надёжный признак успешной привязки — наличие data.instance_user_id в ответе. Сама ситуация — не ошибка интеграции: сначала отправьте клиента через /users/sync, затем повторите связывание.


Переходы по ссылкам из рассылок

Когда клиент переходит на сайт по ссылке из письма Октопус, к адресу добавляется метка utm_oct. По ней вы можете опознать посетителя ещё до того, как он вошёл в аккаунт, и связать с ним сессию.

https://example.ru/catalog/kurtki/?utm_source=octopus&utm_oct=1042.1789123456.9f8e7d...

Метка состоит из трёх частей, разделённых точкой:

<идентификатор клиента>.<срок действия>.<подпись>
ЧастьОписание
Идентификатор клиентаВаш идентификатор клиента — тот ID, который вы передавали в /users/sync. Если он состоит только из цифр, записан как есть: 1042. Любой другой закодирован: знак ~ и дальше base64url без дополнения =, например cust_123~Y3VzdF8xMjM
Срок действияВремя, до которого метка действительна, в секундах Unix
ПодписьHMAC-SHA256 от первых двух частей метки в том виде, в каком они пришли, вместе с точкой между ними: ~Y3VzdF8xMjM.1789123456. Ключ подписи — API-ключ основного коннектора проекта

Примеры меток:

1042.1789123456.9f8e7d...           ← идентификатор «1042»
~Y3VzdF8xMjM.1789123456.a1b2c3... ← идентификатор «cust_123»

Кодирование нужно, чтобы метка не ломалась: в идентификаторе могут быть точки, @, + и другие символы, которые нельзя оставить в ссылке. В закодированном виде метка состоит только из безопасных символов, и точек в ней ровно две.

Как обработать метку:

  1. Возьмите из адреса параметр utm_oct и разделите по точке на три части.
  2. Убедитесь, что срок действия ещё не истёк.
  3. Пересчитайте подпись от первых двух частей своим ключом и сравните с присланной — обязательно сравнением, устойчивым к разнице во времени выполнения.
  4. Раскодируйте идентификатор: если первая часть начинается с ~, отбросьте этот знак и раскодируйте остаток из base64url; иначе это и есть идентификатор.
  5. Вызовите связывание сессии с клиентом с этим идентификатором и дальше передавайте его как USER_ID во всех событиях этой сессии.

Подпись проверяется до раскодирования — по частям метки ровно в том виде, в каком они пришли.

import base64, hashlib, hmac, time

def parse_utm_oct(token: str, api_key: str) -> str | None:
parts = token.split('.')
if len(parts) != 3:
return None
raw_id, exp, signature = parts
if not exp.isdigit() or time.time() > int(exp):
return None
expected = hmac.new(api_key.encode(), f'{raw_id}.{exp}'.encode(), hashlib.sha256).hexdigest()
if not hmac.compare_digest(expected, signature):
return None
if raw_id.startswith('~'):
encoded = raw_id[1:]
return base64.urlsafe_b64decode(encoded + '=' * (-len(encoded) % 4)).decode()
return raw_id

Требования и особенности:

  • метку обязательно проверять по подписи: без проверки любой посетитель сможет подставить чужой идентификатор в адресе и получить доступ к чужой истории;
  • срок жизни метки — 180 дней;
  • идентификатор из цифр храните и сравнивайте как строку: ведущие нули значимы, 007 и 7 — разные клиенты;
  • запомните опознанного посетителя у себя (в своей сессии или в собственной cookie), чтобы не разбирать метку на каждой странице;
  • ключ подписи — у основного коннектора проекта. Если вы подключили дополнительный коннектор, его ключ для проверки не подойдёт: запросите ключ основного;
  • метка появляется только у клиентов, переданных с ID. Клиентам, заведённым вручную в кабинете или загруженным без идентификатора, она не добавляется: вашей системе такой клиент неизвестен.

Добавление в корзину

Событие «положил товар в корзину» — по одному вызову на добавление.

POST /tracking/basket-add
{
"SESSID": "a1b2c3d4e5f60718",
"USER_ID": "1042",
"XML_ID": "5501",
"PRODUCT_NAME": "Куртка зимняя Аврора",
"PRICE": 12900,
"QUANTITY": 1,
"DATETIME": "2026-09-18 10:16:02"
}
ПолеОбязательноОписание
SESSIDдаИдентификатор сессии
XML_IDдаВаш идентификатор товара
PRODUCT_NAMEдаНазвание товара
PRICEдаЦена за единицу
QUANTITYнетКоличество. По умолчанию 1
USER_IDнетВаш идентификатор клиента, если посетитель опознан
PROPERTIESнетДополнительные свойства позиции
DATETIMEнетВремя события

Состояние корзины

Основной метод для сценариев брошенной корзины. Вы присылаете полное текущее содержимое корзины, а платформа сама вычисляет, что добавилось, что изменилось в количестве и что было удалено.

POST /tracking/basket-sync
{
"SESSID": "a1b2c3d4e5f60718",
"USER_ID": "1042",
"ITEMS": [
{
"xml_id": "5501",
"name": "Куртка зимняя Аврора",
"price": 12900,
"quantity": 1,
"date_insert": "2026-09-18 10:16:02",
"properties": [
{ "code": "COLOR", "name": "Цвет", "value": "синий" }
]
},
{
"xml_id": "5601",
"name": "Футболка Базовая, M",
"price": 1900,
"quantity": 2
}
]
}
Регистр имён полей не важен

И в теле запроса, и внутри позиций ITEMS поле распознаётся в любом написании: xml_id, XML_ID и Xml_Id — одно и то же. Имена свойств внутри properties остаются как есть, их платформа не трогает.

ПолеОбязательноОписание
SESSIDдаИдентификатор сессии посетителя
ITEMSдаМассив позиций корзины. Пустой массив [] допустим — так фиксируется очистка
USER_IDнетВаш идентификатор клиента, если посетитель опознан

Поля позиции внутри ITEMS:

Поле позицииОбязательноОписание
xml_idдаВаш идентификатор товара
nameдаНазвание товара
priceдаЦена за единицу
quantityдаКоличество
date_insertнетКогда позиция попала в корзину
propertiesнетМассив свойств: code, name, value

Требования и особенности:

  • отправляйте корзину целиком при любом изменении — добавлении, изменении количества, удалении позиции;
  • пустая корзина — это "ITEMS": [], так фиксируется полная очистка;
  • достаточно одного вызова на изменение: если посетитель за раз изменил несколько позиций, пришлите итоговое состояние один раз.

Ответ

{
"success": true,
"code": 200,
"message": "Корзина синхронизирована",
"data": {
"changes_count": 2,
"changes": [
{ "action": "add", "quantity": 1, "item": { "xml_id": "5501" } },
{ "action": "remove", "quantity": -2, "item": { "xml_id": "5499" } }
]
}
}

В changes возвращается, что именно платформа считает изменением: add — позиция появилась, update — изменилось количество (в quantity разница), remove — позиция исчезла. Разбирать этот массив не обязательно, он полезен при отладке.


Что дальше

  • Фиксировать конверсии и ключевые действия — «Цели».