TEASEDocs
На русском

TG-атрибуция продаж

Откуда пришёл каждый платящий Telegram-фанат — точный матч по deep-link, расчётный матч по стране и времени и честный бейдж точности на каждой строке.

Воронка заканчивается не только на OnlyFans — часть трафика уходит прямыми редиректами в Telegram-бот продаж, и этот бот приносит собственные деньги. TG-атрибуция отвечает на тот же вопрос, что и Атрибуция для OnlyFans, но для бота: какой из ваших доменов привёл каждого платящего Telegram-покупателя и сколько он заплатил?

Нюанс: в бота попадают через обычный редирект, поэтому большинство фанатов приходят без трекинг-метки. Поэтому TEASE разрешает каждого фаната слоями — точный матч там, где он есть, расчётный матч по стране и времени для основной массы и честная «органика» в остатке — и ставит на каждую строку бейдж точности, чтобы расчёт никогда не выдавался за факт.

Ментальная модель

Каждый Telegram-фанат разрешается ровно к одному kind:

kindТочностьЗначение
cidexact — «точно»Фанат запустил бота по отслеживаемому deep-link с клик-id, и этот клик разрешается к вашему домену. Железно — но редко: повседневный редирект в бота метку не несёт.
tg_matchapprox — «расчёт»Ближайший предшествующий клик в сторону Telegram из той же страны в окне 5 минут. Этот уровень несёт основную массу атрибуции.
organicapprox — «расчёт»Ни того, ни другого — честная остаточная корзина «Органика (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_fromintegerнетНачало окна, unix-секунды. 0 = с самого начала.
period_tointegerнетКонец окна, 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"
}

Поля верхнего уровня

ПолеТипОписание
summaryobjectЗаголовок: fans (приходы в окне), payers (уникальные фанаты с положительным net в окне, старые включены), revenue_net_cents (net всех продаж окна), msg5plus (пришедшие, написавшие больше 5 сообщений).
funnelobjectВоронка когорты прихода: arrivedmsg5pluspayers (плательщики среди пришедших).
leaderboardarrayПо строке на разрешённый домен-источник, сортировка по revenue_net_cents по убыванию. Строку получают только фанаты cid / tg_match с доменом — всё остальное уходит в organic.
organicobjectОстаточная корзина, та же форма строки. Присутствует всегда.
countriesarrayСвод по странам поверх всех источников — см. ниже.
trendarrayВременной ряд arrivals, payers, revenue_net_cents по бакетам.
trend_unitstringhour для окон до 48 часов, иначе day. Бакеты в UTC; на ограниченных окнах ряд непрерывный (пустые бакеты — нули), чтобы график не был дырявым.

Поля строки источника

ПолеТипОписание
domain_sourcestringДомен-источник. Пусто у строки organic.
source_labelstringДружелюбное имя источника — то же display-имя, что и в лидерборде «Доход».
source_iconstringКлюч бренд-иконки источника, как в денежном лидерборде; может быть пустым.
kindstringcid, tg_match или organic — класс точности строки.
fansintegerНовые приходы этого источника в окне.
spendersintegerУникальные фанаты источника с положительным net в окне (старые включены).
msg5plusintegerПришедшие этого источника, написавшие больше 5 сообщений.
revenue_net_centsintegerNet продаж источника в окне.
pctfloatДоля от Telegram-net всего окна, 0–100.
countriesarrayДеньги источника по странам фанатов: { country, revenue_net_cents }, сортировка по деньгам.
usersarrayПлатящие фанаты за строкой (топ-50 по net в окне): fan_id, username, country, revenue_net_cents, first_ts. fan_id открывает карточку фаната.
nonpayersarrayПришедшие от источника, но не заплатившие в периоде (топ-60, самые вовлечённые первыми): fan_id, username, country, message_count, first_ts. Ваш лучший список для креативов и таргетинга.

Поля строки страны

ПолеТипОписание
countrystringКод ISO-3166 alpha-2 (пусто, когда неизвестно).
fansintegerПриходы из этой страны в окне.
spendersintegerУникальные плательщики из этой страны в окне.
revenue_net_centsintegerNet-выручка из этой страны в окне.
msg10plusintegerПришедшие из этой страны, написавшие больше 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 / countrystringsИдентичность, как её знает бот.
originobjectРазрешённый источник: kind, человеческий label, source, domain, country и бейдж precision (exact / approx) — контракт выше.
total_net_cents / purchasesintegersПожизненный net и число покупок.
message_countintegerСообщений от фаната за всё время.
closeness_level / closeness_scorestring / integerОценка близости фаната по данным бота.
first_ts / last_ts / last_purchase_tsintegersПервое сообщение, последнее сообщение, последняя покупка контента (unix-секунды).
blockedbooleanЗаблокировал ли фанат бота.
summary_text / preferred_name / conversion / paywall_triggers / active_hoursmixedЖивое обогащение из карточки фаната в самом боте (саммари переписки, как фанат просит себя называть, шаг воронки, срабатывания пейволла, активные часы 0–23). Fail-safe: когда API бота недоступен, эти поля приходят пустыми, а карточка всё равно рендерится из локальных данных.
by_dayarrayРяд net по дням: { day, net_cents }.
transactionsarrayНовые первыми: { ts, net_cents, gross_cents, kind }.
purchasedarrayГалерея купленного контента (только покупки контента — чаевые плитку не создают): итоги по позиции плюс метаданные каталога (description, tags, level, level_label, media_count, media_types, in_catalog).

В панели

Этот же отчёт — режим «Telegram» на дашборде: воронка, тренд «Приход и оплаты», лидерборд «Источники» (чип фаната открывает карточку выше) и «Страны». На каждой строке источника и в каждой карточке — бейдж точности, так что «точно» vs «расчёт» всегда виден рядом с деньгами.

Частые вопросы

Дальнейшие шаги

  • Атрибуция — лидерборд выручки OnlyFans, который этот отчёт зеркалит.
  • Маршрутизация воронки — какие страны и домены отправляют трафик в Telegram.
  • Лендинги — гео-сегменты и прямые редиректы, ведущие фанатов в Telegram.

On this page