Визиты и корзина
Трекинг даёт платформе поведение посетителя: какие страницы он смотрел, что положил в корзину и когда. На этом строятся сегменты вроде «смотрел раздел, но не купил» и сценарии брошенной корзины.
Визиты и цели с сайта не обязательно отправлять самим: есть 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»
Кодирование нужно, чтобы метка не ломалась: в идентификаторе могут быть точки, @, + и другие символы, которые нельзя оставить в ссылке. В закодированном виде метка состоит только из безопасных символов, и точек в ней ровно две.
Как обработать метку:
- Возьмите из адреса параметр
utm_octи разделите по точке на три части. - Убедитесь, что срок действия ещё не истёк.
- Пересчитайте подпись от первых двух частей своим ключом и сравните с присланной — обязательно сравнением, устойчивым к разнице во времени выполнения.
- Раскодируйте идентификатор: если первая часть начинается с
~, отбросьте этот знак и раскодируйте остаток из base64url; иначе это и есть идентификатор. - Вызовите связывание сессии с клиентом с этим идентификатором и дальше передавайте его как
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 — позиция исчезла. Разбирать этот массив не обязательно, он полезен при отладке.
Что дальше
- Фиксировать конверсии и ключевые действия — «Цели».