TG-атрибуция продаж
Откуда пришёл каждый платящий Telegram-фанат — точный матч по deep-link, расчётный матч по стране и времени и честный бейдж точности на каждой строке.
Воронка заканчивается не только на OnlyFans — часть трафика уходит прямыми редиректами в Telegram-бот продаж, и этот бот приносит собственные деньги. TG-атрибуция отвечает на тот же вопрос, что и Атрибуция для OnlyFans, но для бота: какой из ваших доменов привёл каждого платящего Telegram-покупателя и сколько он заплатил?
Нюанс: в бота попадают через обычный редирект, поэтому большинство фанатов приходят без трекинг-метки. Поэтому TEASE разрешает каждого фаната слоями — точный матч там, где он есть, расчётный матч по стране и времени для основной массы и честная «органика» в остатке — и ставит на каждую строку бейдж точности, чтобы расчёт никогда не выдавался за факт.
Ментальная модель
Каждый Telegram-фанат разрешается ровно к одному kind:
kind | Точность | Значение |
|---|---|---|
cid | exact — «точно» | Фанат запустил бота по отслеживаемому deep-link с клик-id, и этот клик разрешается к вашему домену. Железно — но редко: повседневный редирект в бота метку не несёт. |
tg_match | approx — «расчёт» | Ближайший предшествующий клик в сторону Telegram из той же страны в окне 5 минут. Этот уровень несёт основную массу атрибуции. |
organic | approx — «расчёт» | Ни того, ни другого — честная остаточная корзина «Органика (TG)». |
Как работает матч по стране и времени
Когда фанат впервые пишет боту, TEASE смотрит на 5 минут назад от этого первого сообщения —
на человеческие клики, которые вели в сторону Telegram (прямые Telegram-редиректы по гео и
Telegram-кнопки лендингов) из той же страны. Побеждает ближайший клик, предшествующий
первому сообщению, — его домен становится источником фаната. Нет подходящего клика в окне (или у
фаната нет страны) → фанат остаётся organic.
Почему именно 5 минут
Человек, которого увели в Telegram, пишет сразу. Замер по боевым данным (2130 фанатов со страной и первым сообщением) показывает разрыв «ближайший клик той же страны → первое сообщение»: до 10 с — 29, 10–60 с — 665, 1–5 мин — 170, 5–30 мин — 31, 30–60 мин — 26, 1–6 ч — 67, 6–24 ч — 45. После пяти минут счёт падает до единиц, а к 1–6 и 6–24 часам снова растёт — это уже не хвост поведения, а случайные совпадения: чем шире окно, тем выше шанс, что в той же стране кто-то кликал по своим делам. Прежнее суточное окно записывало такие совпадения в заслугу домену.
Ширину окна можно изменить без выкатки — переменная TG_MATCH_WINDOW_SEC (в секундах) в
окружении API. Значение по умолчанию — 300; мусор и неположительные значения откатываются к
нему же. Расширяя окно, помните: атрибуции станет больше, но она станет менее правдивой.
Бейдж точности не врёт
precision равен exact только при настоящем первом касании через cid. Матч по стране и
времени — это вычисление, поэтому он всегда помечен approx; а матч, который не может назвать
домен, честно деградирует в organic, вместо того чтобы выдумывать источник. Показывайте бейдж
рядом с деньгами и никогда не подавайте approx-строку как измеренный факт.
Две честные линзы
Отчёт намеренно совмещает два окна — ровно так же, как отчитывается сам бот:
- Выручка (деньги) — каждая продажа внутри окна, датированная продажей и
атрибутированная к источнику заплатившего фаната. Старый фанат (первое сообщение задолго до
окна), заплативший сегодня, считается сегодня. Это питает
summary.payers,summary.revenue_net_cents, деньги лидерборда,countriesи выручку/плательщиков в тренде. - Привлечение (воронка) — когорта прихода: фанаты, чьё первое сообщение попало в окно,
проведённые по шагам пришло → написали 5+ сообщений → заплатили (в периоде). Это питает
summary.fans,funnel, пофаночныеfans/msg5plus/nonpayersисточников и приходы в тренде.
Почему fans и payers не сверяются друг с другом
summary.fans считает новые приходы, а summary.payers — всех, кто заплатил в окне,
включая старых фанатов. Поэтому источник может показывать реальные деньги при нуле новых
приходов (его старые фанаты продолжают платить), а funnel.payers (плательщики среди
пришедших) всегда ≤ summary.payers.
Чтение отчёта
GET /api/admin/tg-attribution возвращает весь отчёт одним чтением в рамках вашего аккаунта.
Все денежные значения — целые центы (net); ответы ненадолго кэшируются на сервере.
curl "https://app.tease.link/api/admin/tg-attribution?period_from=1751328000&period_to=0" \
-H "Authorization: Bearer $TEASE_API_KEY"const res = await fetch(
'https://app.tease.link/api/admin/tg-attribution?period_from=1751328000&period_to=0',
{ headers: { Authorization: `Bearer ${process.env.TEASE_API_KEY}` } },
);
const report = await res.json();import os, requests
res = requests.get(
"https://app.tease.link/api/admin/tg-attribution",
headers={"Authorization": f"Bearer {os.environ['TEASE_API_KEY']}"},
params={"period_from": 1751328000, "period_to": 0},
)
report = res.json()Query-параметры
| Поле | Тип | Обязательно | Описание |
|---|---|---|---|
period_from | integer | нет | Начало окна, unix-секунды. 0 = с самого начала. |
period_to | integer | нет | Конец окна, unix-секунды. 0 = до текущего момента. |
Ответ
{
"summary": { "fans": 214, "payers": 57, "revenue_net_cents": 331900, "msg5plus": 122 },
"funnel": { "arrived": 214, "msg5plus": 122, "payers": 31 },
"leaderboard": [
{
"domain_source": "вашдомен.com",
"source_label": "Main IG",
"source_icon": "instagram",
"kind": "tg_match",
"fans": 96,
"spenders": 24,
"msg5plus": 61,
"revenue_net_cents": 182400,
"pct": 55.0,
"countries": [
{ "country": "DE", "revenue_net_cents": 96100 },
{ "country": "AE", "revenue_net_cents": 51200 }
],
"users": [
{ "fan_id": "7093412885", "username": "fan_handle", "country": "DE",
"revenue_net_cents": 44900, "first_ts": 1752537600 }
],
"nonpayers": [
{ "fan_id": "7093412901", "username": "quiet_fan", "country": "DE",
"message_count": 18, "first_ts": 1752882000 }
]
}
],
"organic": {
"domain_source": "", "source_label": "Органика (TG)", "source_icon": "",
"kind": "organic", "fans": 84, "spenders": 21, "msg5plus": 40,
"revenue_net_cents": 101800, "pct": 30.7,
"countries": [], "users": [], "nonpayers": []
},
"countries": [
{ "country": "DE", "fans": 41, "spenders": 12,
"revenue_net_cents": 121300, "msg10plus": 9 }
],
"trend": [
{ "date": "2026-07-18", "arrivals": 24, "payers": 6, "revenue_net_cents": 21500 }
],
"trend_unit": "day"
}Поля верхнего уровня
| Поле | Тип | Описание |
|---|---|---|
summary | object | Заголовок: fans (приходы в окне), payers (уникальные фанаты с положительным net в окне, старые включены), revenue_net_cents (net всех продаж окна), msg5plus (пришедшие, написавшие больше 5 сообщений). |
funnel | object | Воронка когорты прихода: arrived → msg5plus → payers (плательщики среди пришедших). |
leaderboard | array | По строке на разрешённый домен-источник, сортировка по revenue_net_cents по убыванию. Строку получают только фанаты cid / tg_match с доменом — всё остальное уходит в organic. |
organic | object | Остаточная корзина, та же форма строки. Присутствует всегда. |
countries | array | Свод по странам поверх всех источников — см. ниже. |
trend | array | Временной ряд arrivals, payers, revenue_net_cents по бакетам. |
trend_unit | string | hour для окон до 48 часов, иначе day. Бакеты в UTC; на ограниченных окнах ряд непрерывный (пустые бакеты — нули), чтобы график не был дырявым. |
Поля строки источника
| Поле | Тип | Описание |
|---|---|---|
domain_source | string | Домен-источник. Пусто у строки organic. |
source_label | string | Дружелюбное имя источника — то же display-имя, что и в лидерборде «Доход». |
source_icon | string | Ключ бренд-иконки источника, как в денежном лидерборде; может быть пустым. |
kind | string | cid, tg_match или organic — класс точности строки. |
fans | integer | Новые приходы этого источника в окне. |
spenders | integer | Уникальные фанаты источника с положительным net в окне (старые включены). |
msg5plus | integer | Пришедшие этого источника, написавшие больше 5 сообщений. |
revenue_net_cents | integer | Net продаж источника в окне. |
pct | float | Доля от Telegram-net всего окна, 0–100. |
countries | array | Деньги источника по странам фанатов: { country, revenue_net_cents }, сортировка по деньгам. |
users | array | Платящие фанаты за строкой (топ-50 по net в окне): fan_id, username, country, revenue_net_cents, first_ts. fan_id открывает карточку фаната. |
nonpayers | array | Пришедшие от источника, но не заплатившие в периоде (топ-60, самые вовлечённые первыми): fan_id, username, country, message_count, first_ts. Ваш лучший список для креативов и таргетинга. |
Поля строки страны
| Поле | Тип | Описание |
|---|---|---|
country | string | Код ISO-3166 alpha-2 (пусто, когда неизвестно). |
fans | integer | Приходы из этой страны в окне. |
spenders | integer | Уникальные плательщики из этой страны в окне. |
revenue_net_cents | integer | Net-выручка из этой страны в окне. |
msg10plus | integer | Пришедшие из этой страны, написавшие больше 10 сообщений. |
Плательщик — это положительный net
Фанат считается плательщиком, только когда его net в окне больше нуля — одинокий рефанд плательщика не делает. Продажи попадают в окно по времени продажи, в UTC.
Карточка одного фаната
GET /api/admin/tg-fan/{user_id} открывает одного Telegram-фаната — идентичность, разрешённый
источник с бейджем точности, пожизненные итоги, ряд net по дням, список транзакций и купленный
контент. Возвращает 404, когда фанат неизвестен (или не ваш — чтение изолировано по аккаунту).
curl "https://app.tease.link/api/admin/tg-fan/7093412885" \
-H "Authorization: Bearer $TEASE_API_KEY"{
"fan_id": "7093412885",
"username": "fan_handle",
"name": "Alex",
"country": "DE",
"origin": {
"kind": "tg_match",
"label": "TG-трафик вашдомен.com",
"source": "вашдомен.com",
"domain": "вашдомен.com",
"country": "DE",
"precision": "approx"
},
"total_net_cents": 44900,
"purchases": 6,
"message_count": 132,
"closeness_level": "warm",
"closeness_score": 62,
"first_ts": 1752537600,
"last_ts": 1753142400,
"last_purchase_ts": 1753056000,
"blocked": false,
"summary_text": "…",
"preferred_name": "Alex",
"conversion": 3,
"paywall_triggers": 2,
"active_hours": [20, 21, 22],
"by_day": [ { "day": "2026-07-18", "net_cents": 9900 } ],
"transactions": [
{ "ts": 1753056000, "net_cents": 9900, "gross_cents": 12900, "kind": "content" }
],
"purchased": [
{
"content_id": "c_412", "net_cents": 19800, "count": 2, "last_ts": 1753056000,
"sale_type": "content", "description": "…", "tags": ["…"],
"level": 2, "level_label": "…", "media_count": 4,
"media_types": { "video": 1, "photo": 3 }, "in_catalog": true
}
]
}Поля карточки
| Поле | Тип | Описание |
|---|---|---|
fan_id / username / name / country | strings | Идентичность, как её знает бот. |
origin | object | Разрешённый источник: kind, человеческий label, source, domain, country и бейдж precision (exact / approx) — контракт выше. |
total_net_cents / purchases | integers | Пожизненный net и число покупок. |
message_count | integer | Сообщений от фаната за всё время. |
closeness_level / closeness_score | string / integer | Оценка близости фаната по данным бота. |
first_ts / last_ts / last_purchase_ts | integers | Первое сообщение, последнее сообщение, последняя покупка контента (unix-секунды). |
blocked | boolean | Заблокировал ли фанат бота. |
summary_text / preferred_name / conversion / paywall_triggers / active_hours | mixed | Живое обогащение из карточки фаната в самом боте (саммари переписки, как фанат просит себя называть, шаг воронки, срабатывания пейволла, активные часы 0–23). Fail-safe: когда API бота недоступен, эти поля приходят пустыми, а карточка всё равно рендерится из локальных данных. |
by_day | array | Ряд net по дням: { day, net_cents }. |
transactions | array | Новые первыми: { ts, net_cents, gross_cents, kind }. |
purchased | array | Галерея купленного контента (только покупки контента — чаевые плитку не создают): итоги по позиции плюс метаданные каталога (description, tags, level, level_label, media_count, media_types, in_catalog). |
В панели
Этот же отчёт — режим «Telegram» на дашборде: воронка, тренд «Приход и оплаты», лидерборд «Источники» (чип фаната открывает карточку выше) и «Страны». На каждой строке источника и в каждой карточке — бейдж точности, так что «точно» vs «расчёт» всегда виден рядом с деньгами.
Частые вопросы
Дальнейшие шаги
- Атрибуция — лидерборд выручки OnlyFans, который этот отчёт зеркалит.
- Маршрутизация воронки — какие страны и домены отправляют трафик в Telegram.
- Лендинги — гео-сегменты и прямые редиректы, ведущие фанатов в Telegram.
Атрибуция
Читайте лидерборд «Источники» — выручка по источнику, стране, ссылке и фанату, сверенная с чистым итогом вашего аккаунта.
Прокладка (турникет-бот)
Свой Telegram-бот на входе трафика — подключение токеном из BotFather, локализованное приветствие, сплит мусора в канал и авто-атрибуция каждого /start.