Аналитика действий и UTM меток

Аналитика: UTM-метки и действия в боте

Один API-раздел для двух вопросов:

  1. Откуда пришли — UTM-метки (рекламные ссылки).
  2. Что делали в боте — действия (просмотр товара, корзина, оплата и т.п.).

Через API можно выгружать Telegram ID, смотреть покупки по метке, собирать сегменты («сделал A, но не сделал B») и считать воронки.

Адрес API: https://api.bot-t.com
Все запросы — POST, тело — JSON.

Запись действий ведётся с тарифа «Расширенный» и выше. Смотреть и выгружать можно, если данные уже есть.


Как подключиться

ПараметрОбязательноЧто это
bot_idдаID вашего бота
токен бота или секретный ключдаtoken / botToken или secretKey

Токен и ключ можно передать в JSON-теле или в query (?token=... / ?secretKey=...).

Content-Type: application/json

Успех:

{ "result": true, "data": { } }

Ошибка:

{ "result": false, "message": "текст ошибки" }

Всегда проверяйте result === true. Лимит: 120 запросов в минуту.

Даты — в часовом поясе бота: 2024-05-01 или 2024-05-01 12:00:00.

Пагинация: limit и offset. В обычных списках до 50 записей, в выгрузках — до 500.

Счётчики UTM (count, count-users, count-users-new) и удаление метки возвращают data строкой: "12" или "1". Остальные методы — объект или массив.

Telegram ID почти всегда лежит внутри пользователя: user.telegram_id. В методах действий users и export (уникальные люди) пользователь лежит сразу в items[], там telegram_id на верхнем уровне.


Чем отличаются UTM и действия

UTM-меткиДействия в боте
ВопросОткуда пришёл человекЧто он делал внутри бота
Примерссылка с кодом promo_mayдобавил в корзину, открыл товар
Префикс API/v1/common/traffic/traffic/.../v1/common/link-track/...

Их можно использовать вместе: сначала аудитория по метке, потом — кто из них (или в целом по боту) не дошёл до оплаты.

Сегменты из аналитики дальше идут в рассылки как обычные группы: group_id/v1/bot/mailing/mailing/set-group.


Карта методов

UTM-метки

ЗадачаАдрес
Список меток/v1/common/traffic/traffic/index
Сколько меток/v1/common/traffic/traffic/count
Выгрузка переходов + Telegram ID/v1/common/traffic/traffic/export
Сводка: переходы и новые/v1/common/traffic/traffic/stats
Кто пришёл по метке/v1/common/traffic/traffic/users-traffic
Кто пришёл впервые/v1/common/traffic/traffic/users-traffic-new
Сколько переходов/v1/common/traffic/traffic/count-users
Сколько новых/v1/common/traffic/traffic/count-users-new
Кто пришёл и какие тарифы купил/v1/common/traffic/traffic/users-traffic-tariff
То же, только новые/v1/common/traffic/traffic/users-traffic-tariff-new
Кто пришёл и какие заказы в магазине/v1/common/traffic/traffic/users-traffic-shop-order
Кто пришёл и какие заказы в корзине/v1/common/traffic/traffic/users-traffic-cart-order
Удалить метку/v1/common/traffic/traffic/delete

Методы с суффиксом -new берут только новых пользователей бота. Без -new — все переходы по метке.

Действия в боте

ЗадачаАдрес
Справочник действий/v1/common/link-track/codes
Готовые воронки/v1/common/link-track/presets
Список событий/v1/common/link-track/index
Число событий/v1/common/link-track/count
Люди по условиям (+ Telegram ID)/v1/common/link-track/users
Сколько таких людей/v1/common/link-track/users-count
Выгрузка/v1/common/link-track/export
Сегмент по действиям/v1/common/link-track/create-segment
Статистика воронки/v1/common/link-track/funnel
Сегмент по шагу воронки/v1/common/link-track/create-segment-funnel

Часть 1. UTM-метки

Что такое UTM-метка

Короткий код в ссылке на бота (например promo_may), до 30 символов.

У метки есть:

  • код — то, что в ссылке. В запросах фильтр называется utm_source, в списке меток поле ответа — link;
  • название — как вы её подписали (title);
  • ID — номер в системе. Нужен для stats, списков людей и отчётов «кто купил».

Список меток

POST /v1/common/traffic/traffic/index

{
  "bot_id": 1,
  "utm_source": "promo_may",
  "limit": 50,
  "offset": 0
}

utm_source и user_id необязательны. limit не больше 50.

Ответ — массив в data:

{
  "result": true,
  "data": [
    {
      "id": 10,
      "bot_id": 1,
      "link": "promo_may",
      "title": "Реклама май",
      "bot_name": "MyShop",
      "transitions": 1500,
      "new_users": 310
    }
  ]
}

Код метки здесь — link, не utm_source.

Счётчик меток: /v1/common/traffic/traffic/count. Тот же utm_source необязателен.

{ "bot_id": 1, "utm_source": "promo_may" }
{ "result": true, "data": "1" }

Сколько перешло и сколько новых

POST /v1/common/traffic/traffic/stats

Нужен ID из списка меток. Можно сузить по user_id.

{
  "bot_id": 1,
  "id": 10,
  "created_time_start": "2024-05-01",
  "created_time_end": "2024-05-31"
}

Ответ:

{
  "result": true,
  "data": {
    "traffic_id": 10,
    "utm_source": "promo_may",
    "title": "Реклама май",
    "transitions": 1500,
    "unique_users": 820,
    "new_users": 310
  }
}
ПолеЧто означает
transitionsСколько раз переходили по ссылке (все клики)
unique_usersСколько уникальных людей перешло
new_usersСколько из них пришли впервые (новые пользователи бота)

Отдельные счётчики (нужен id метки). data — строка:

ЗадачаАдресОтвет
Только переходы/v1/common/traffic/traffic/count-users{ "result": true, "data": "1500" }
Только новые/v1/common/traffic/traffic/count-users-new{ "result": true, "data": "310" }
{
  "bot_id": 1,
  "id": 10,
  "created_time_start": "2024-05-01",
  "created_time_end": "2024-05-31"
}

Выгрузить Telegram ID по метке

POST /v1/common/traffic/traffic/export

{
  "bot_id": 1,
  "utm_source": "promo_may",
  "created_time_start": "2024-05-01",
  "created_time_end": "2024-05-31",
  "only_new": true,
  "unique": true,
  "limit": 500,
  "offset": 0
}
ПараметрЗачем
utm_sourceКод метки. Можно не передавать — тогда все метки бота. Несуществующий код — ошибка UTM-метка не найдена
created_time_start / created_time_endПериод переходов
only_newТолько новые. По умолчанию false
uniqueБез повторов одного человека. По умолчанию false
limit / offsetПорциями, до 500. Если limit нет — 50

Ответ — массив. Telegram ID в user.telegram_id:

{
  "result": true,
  "data": [
    {
      "id": 501,
      "traffic_id": 10,
      "utm_source": "promo_may",
      "title": "Реклама май",
      "user": {
        "id": 88,
        "telegram_id": 123456789,
        "username": "ivan",
        "first_name": "Иван",
        "last_name": "Петров",
        "link": "@ivan",
        "type": "private"
      },
      "created_at": 1714521600,
      "created_time": "2024-05-01 12:00:00"
    }
  ]
}

Кто пришёл по конкретной метке

Нужен ID метки. limit не больше 50.

Все переходы:

POST /v1/common/traffic/traffic/users-traffic

Только новые:

POST /v1/common/traffic/traffic/users-traffic-new

{
  "bot_id": 1,
  "id": 10,
  "created_time_start": "2024-05-01",
  "created_time_end": "2024-05-31",
  "limit": 50,
  "offset": 0
}

Можно передать user_id.

Ответ — массив:

{
  "result": true,
  "data": [
    {
      "id": 501,
      "user": {
        "id": 88,
        "telegram_id": 123456789,
        "username": "ivan",
        "first_name": "Иван",
        "last_name": "Петров",
        "link": "@ivan",
        "type": "private"
      },
      "created_at": 1714521600,
      "created_time": "2024-05-01 12:00:00"
    }
  ]
}

Счётчик новых: /v1/common/traffic/traffic/count-users-new.


Кто пришёл и что купил

Все методы ниже требуют bot_id и id метки. Telegram ID — в user.telegram_id.

Это не «только купившие». В ответе все, кто пришёл за период. У кого нет покупок: has_purchases: false / has_orders: false. Сами отфильтруйте true, если нужны только покупатели.

Тариф (подписка)

Все пришедшие: /v1/common/traffic/traffic/users-traffic-tariff
Только новые: /v1/common/traffic/traffic/users-traffic-tariff-new

{
  "bot_id": 1,
  "id": 10,
  "created_time_start": "2024-05-01",
  "created_time_end": "2024-05-31",
  "paid_time_start": "2024-05-01",
  "paid_time_end": "2024-05-31",
  "limit": 50,
  "offset": 0
}
  • даты перехода — когда пришли по метке;
  • даты оплаты — какие тарифы показать в карточке.
{
  "result": true,
  "data": [
    {
      "id": 501,
      "user": { "id": 88, "telegram_id": 123456789 },
      "created_at": 1714521600,
      "created_time": "2024-05-01 12:00:00",
      "has_purchases": true,
      "tariffs": [
        {
          "id": 9,
          "title": "Месяц",
          "paid_time": "15.05.2024 18:40",
          "resource_title": "Канал"
        }
      ],
      "message": null
    }
  ]
}

Без покупок: has_purchases: false, tariffs: [], message: «Пользователь не купил ни одного тарифа».

Заказ в магазине

POST /v1/common/traffic/traffic/users-traffic-shop-order

Нужен магазин у бота, иначе ошибка Shop not found for bot.

{
  "bot_id": 1,
  "id": 10,
  "created_time_start": "2024-05-01",
  "created_time_end": "2024-05-31",
  "order_time_start": "2024-05-01",
  "order_time_end": "2024-05-31",
  "limit": 50,
  "offset": 0
}

Если заданы order_time_*, люди без заказов в этом диапазоне не попадут в ответ.

{
  "result": true,
  "data": [
    {
      "id": 501,
      "user": { "id": 88, "telegram_id": 123456789 },
      "created_at": 1714521600,
      "created_time": "2024-05-01 12:00:00",
      "has_orders": true,
      "total_orders_count": 2,
      "orders": [
        {
          "id": 77,
          "created_time": "16.05.2024 11:20",
          "price": "990 ₽",
          "status": "Оплачен"
        }
      ],
      "message": null
    }
  ]
}

В карточке не больше 10 заказов. Если заказов больше — в message будет сколько ещё осталось.

Заказ в корзине

POST /v1/common/traffic/traffic/users-traffic-cart-order

Тот же набор полей, что у магазина. Тоже нужен магазин у бота.


Удалить метку

POST /v1/common/traffic/traffic/delete

{ "bot_id": 1, "id": 10 }

Несколько сразу: "id": [10, 11].

{ "result": true, "data": "1" }

Часть 2. Действия в боте

Что такое действие

Короткая запись: кто, что сделал, когда.

ПолеСмысл
codeТип действия (ka — в корзину, cn — карточка товара…)
code_intНомер объекта (товар, сообщение, сценарий), если нужен
user.telegram_idID в Telegram

Сначала возьмите справочник кодов — набор зависит от типа бота.


Справочник действий

POST /v1/common/link-track/codes

{ "bot_id": 1 }
{
  "result": true,
  "data": [
    {
      "group": "cart",
      "group_title": "Корзина",
      "codes": [
        { "code": "ka", "title": "Добавил в корзину" },
        { "code": "ko", "title": "Оформление корзины" }
      ]
    }
  ]
}

Примеры:

КодСмысл
ssКоманда /start
caПросмотр товара в боте
cnКарточка товара
kaДобавил в корзину
koОформление корзины
riОткрыл пополнение
rpПополнил баланс
pyУспешная оплата
scЗапуск сценария

Условия аудитории

Методы users, users-count, export, create-segment принимают:

ПолеСмысл
includeДействия, которые должны быть
excludeДействия для исключения или второго условия
modeКак комбинировать
created_time_start / created_time_endПериод
code / code_intКороткий вариант вместо include

Режимы mode

modeРезультат
diffСделали include, но не сделали exclude (так будет, если exclude есть, а mode пустой)
intersectСделали и include, и exclude
includeТолько include

Если exclude нет и mode пустой — считается include.

"include": { "code": "ka" }
"include": [
  { "code": "ka" },
  { "code": "kb" }
]

Несколько кодов в include = «сделал хотя бы одно».
Несколько в exclude = «сделал хотя бы одно из исключающих» (в diff таких отбрасываем).


«Сделал A, но не сделал B» → сегмент

POST /v1/common/link-track/create-segment

Добавляли в корзину, но не оформляли:

{
  "bot_id": 1,
  "title": "Корзина без оформления — май",
  "include": { "code": "ka" },
  "exclude": { "code": "ko" },
  "mode": "diff",
  "created_time_start": "2024-05-01",
  "created_time_end": "2024-05-31"
}

Ответ:

{
  "result": true,
  "data": {
    "group_id": 42,
    "title": "Корзина без оформления — май",
    "count": 128,
    "mode": "diff"
  }
}

group_id дальше идёт в /v1/bot/mailing/mailing/set-group или в /v1/bot/group/....

Смотрели карточку товара №15, но не оплатили:

{
  "bot_id": 1,
  "title": "Смотрели товар 15 без оплаты",
  "include": { "code": "cn", "code_int": 15 },
  "exclude": { "code": "py" },
  "mode": "diff",
  "created_time_start": "2024-05-01",
  "created_time_end": "2024-05-31"
}

Открывали пополнение и реально пополнили:

{
  "bot_id": 1,
  "title": "Открыли и пополнили",
  "include": { "code": "ri" },
  "exclude": { "code": "rp" },
  "mode": "intersect"
}

intersect поле exclude — это второе обязательное действие.)

Просто все, кто добавил в корзину:

{
  "bot_id": 1,
  "title": "Добавляли в корзину",
  "code": "ka",
  "created_time_start": "2024-05-01",
  "created_time_end": "2024-05-31"
}

Если никого нет — сегмент не создаётся, в message: «Нет пользователей по выбранным условиям.»
Без title — «Укажите название сегмента.»
Без действий — «Укажите хотя бы одно действие в include (code).»


Люди и выгрузка Telegram ID по действиям

Список уникальных людей

POST /v1/common/link-track/users

limit до 500 (если не передан — 50).

{
  "bot_id": 1,
  "include": { "code": "ka" },
  "exclude": { "code": "ko" },
  "mode": "diff",
  "created_time_start": "2024-05-01",
  "created_time_end": "2024-05-31",
  "limit": 500,
  "offset": 0
}
{
  "result": true,
  "data": {
    "total": 128,
    "mode": "diff",
    "items": [
      {
        "id": 88,
        "telegram_id": 123456789,
        "username": "ivan",
        "first_name": "Иван",
        "last_name": "Петров",
        "link": "@ivan",
        "type": "private"
      }
    ]
  }
}

Счётчик: /v1/common/link-track/users-count — тот же фильтр, ответ { "total": 128, "mode": "diff" }.

Выгрузка

POST /v1/common/link-track/export

Если unique не передан — считается true. Если есть include или exclude, всегда возвращаются уникальные люди (как users).

{
  "bot_id": 1,
  "include": { "code": "ka" },
  "exclude": { "code": "py" },
  "mode": "diff",
  "unique": true,
  "limit": 500,
  "offset": 0
}

Сырые события: "unique": false и обычный code без include / exclude. Тогда data как у журнала: { "total": 20, "items": [ ...события ] }.


Журнал событий

POST /v1/common/link-track/index

code обязателен. limit до 50.

{
  "bot_id": 1,
  "code": "cn",
  "code_int": 15,
  "created_time_start": "2024-05-01",
  "created_time_end": "2024-05-31",
  "limit": 50,
  "offset": 0
}
{
  "result": true,
  "data": {
    "total": 20,
    "items": [
      {
        "id": "6650ab12f1a2b3c4d5e6f789",
        "code": "cn",
        "code_title": "Карточка товара",
        "code_int": 15,
        "user": {
          "id": 88,
          "telegram_id": 123456789,
          "username": "ivan",
          "first_name": "Иван",
          "last_name": "Петров",
          "link": "@ivan",
          "type": "private"
        },
        "created_at": 1714521600,
        "created_time": "2024-05-01 12:00:00"
      }
    ]
  }
}

Счётчик: /v1/common/link-track/count — тот же фильтр, ответ { "total": 20 }.
Без code — «Укажите код действия (code).»


Воронка по действиям

Готовые воронки

POST /v1/common/link-track/presets

{ "bot_id": 1 }

Набор зависит от типа бота. Ключ из ответа передавайте в preset.

Тип ботаКлючНазвание
Магазин с корзинойcart_purchaseПокупка через корзину (шаги 0–6, оплата — 6)
Магазин с корзинойcart_dropГде теряем корзину
Цифровой магазинshop_purchaseПокупка цифрового товара
Цифровой магазинshop_searchПокупка через поиск
ПодпискиsubscriptionОформление подписки
Есть модуль балансаbalanceПополнение баланса
Любойreferral, feedbackРефералка и форма

cart_purchase есть только у бота с корзиной. Для цифрового магазина берите shop_purchase.

Посчитать воронку

POST /v1/common/link-track/funnel

Это воронка по всему боту, не по одной UTM-метке. transitions часто будет 0.

only_new: true — база только из новых пользователей за период.

{
  "bot_id": 1,
  "preset": "cart_purchase",
  "created_time_start": "2024-05-01",
  "created_time_end": "2024-05-31"
}

Своя воронка — title здесь название воронки:

{
  "bot_id": 1,
  "title": "Корзина → оплата",
  "steps": [
    { "label": "В корзину", "codes": ["ka"] },
    { "label": "Оформление", "codes": ["ko"] },
    { "label": "Оплата", "codes": ["py"] }
  ],
  "created_time_start": "2024-05-01",
  "created_time_end": "2024-05-31"
}
{
  "result": true,
  "data": {
    "title": "Покупка через корзину",
    "users": 500,
    "transitions": 0,
    "steps": [
      {
        "label": "Смотрел категорию",
        "codes": ["cv"],
        "code_int": null,
        "users": 500,
        "percent_total": 100,
        "percent_prev": 100,
        "lost": 0
      }
    ]
  }
}
ПолеСмысл
transitionsПереходов по метке (для общей воронки бота обычно 0)
usersУникальных людей в базе воронки
steps[].usersДошли до шага
steps[].lostОтвалились относительно прошлого шага
steps[].percent_total / percent_prevДоли в %
steps[].codes / code_intКакие действия входят в шаг

Неизвестный preset — «Воронка не найдена: …».

Сегмент по шагу воронки

POST /v1/common/link-track/create-segment-funnel

modeКто попадёт
reachedДошли до шага (значение по умолчанию)
lostБыли в базе периода, но шаг не сделали

title — название сегмента. Для своей воронки шаги в steps, название воронки — funnel_title (не title).

{
  "bot_id": 1,
  "title": "Не дошли до оплаты",
  "preset": "cart_purchase",
  "step": 6,
  "mode": "lost",
  "created_time_start": "2024-05-01",
  "created_time_end": "2024-05-31"
}

step — с нуля, как в presets / funnel. Для cart_purchase шаг 6 — «Оплатил». Без step — вся база воронки за период.

{
  "result": true,
  "data": {
    "group_id": 43,
    "title": "Не дошли до оплаты",
    "count": 90,
    "mode": "lost",
    "step": 6
  }
}

Типичные сценарии

Сколько перешло по рекламе и сколько из них новых

  1. Найти метку в traffic/index, взять id (код смотреть в link).
  2. traffic/stats с датами → взять transitions, unique_users, new_users.

Выгрузить Telegram ID по рекламе за май

  1. traffic/export с кодом метки, датами, при необходимости unique / only_new.
  2. Собрать user.telegram_id со всех страниц.

Кто пришёл по метке и купил

  1. Найти метку в traffic/index, взять id.
  2. users-traffic-tariff-new или отчёт по заказам с датами.
  3. Оставить записи с has_purchases: true / has_orders: true.

Рассылка «бросили корзину»

  1. link-track/create-segment с include: ka, exclude: ko (или py), mode: diff.
  2. group_id передать в /v1/bot/mailing/mailing/set-group.

Смотрели товар, не купили — выгрузить ID

  1. link-track/users или export с include: {code: cn, code_int: 15}, exclude: {code: py}, mode: diff.
  2. Собрать items[].telegram_id.

Найти узкое место воронки

  1. presets → выбрать ключ своего типа бота.
  2. funnel за период → смотреть lost и percent_prev.
  3. create-segment-funnel с mode: lost на проблемном шаге.

Сначала оценить аудиторию, потом сегмент

  1. users-count с нужными условиями.
  2. Если объём ок — create-segment или export.