Документация API
API Trafsly для интеграции Telegram-ботов: получение заданий обязательной подписки, проверка выполнения, баланс рекламодателя, статистика и вебхуки внешних провайдеров.
https://api.trafsly.com
JSON API
Header auth: Auth
v0.2.0
Все эндпоинты защищены API-токеном бота из вашего кабинета в @TrafslyBot. Запросы и ответы — JSON в UTF-8, время в ISO 8601.
Авторизация
Передавайте API-токен из настроек вашего бота в заголовке каждого запроса. Токен начинается с префикса at_.
Auth: at_xxxxxxxxxxxxxxxxxxxxxxxxxxxx
Content-Type: application/json
Где взять токен
Откройте @TrafslyBot → меню Мои боты → выберите бот → API-токен.
Получить задания
Возвращает список спонсорских заданий (каналы и боты для подписки) для пользователя. Если у пользователя нет невыполненных заданий, бот может пропускать его в основной флоу.
Request Body
{
"user_id": 123456789,
"chat_id": 123456789,
"first_name": "Иван",
"username": "ivan_durov",
"language_code": "ru",
"is_premium": false,
"max_sponsors": 5,
"action": "subscribe"
}
| Параметр | Тип | Обязательно | Описание |
|---|---|---|---|
user_id | integer | Да | Telegram ID пользователя |
chat_id | integer | Нет | Telegram ID чата (если запрос идёт из группы) |
first_name | string | Нет | Имя пользователя для персонализации |
username | string | Нет | Username пользователя без @ |
language_code | string | Нет | Локаль пользователя. По умолчанию "ru" |
is_premium | boolean | Нет | Есть ли Telegram Premium. По умолчанию false |
max_sponsors | integer | Нет | Сколько заданий вернуть. По умолчанию — из настроек бота |
action | string | Нет | Контекст запроса. По умолчанию "subscribe" |
Response — у пользователя нет невыполненных заданий
{
"status": "ok",
"sponsors": [],
"message": "User can proceed"
}
Response — есть задания для выполнения
{
"status": "warning",
"sponsors": [
{
"ads_id": 10421,
"link": "https://t.me/cryptonews",
"resource_type": "channel",
"title": "Crypto News",
"status": "unsubscribed"
},
{
"ads_id": 10422,
"link": "https://t.me/SomeBot?start=ref_xyz",
"resource_type": "bot",
"title": "Some Bot",
"status": "unsubscribed"
}
]
}
status: "warning" покажите юзеру список sponsors с кнопками «Подписаться» (ведут на link) и кнопкой «Я подписался». По нажатию вызывайте /confirm-subscription для каждого ads_id.
Через API возвращаются только наши собственные задания Trafsly — никаких сторонних рекламных сетей в SDK-флоу нет.
cURL
curl -X POST https://api.trafsly.com/api/v1/get-sponsors \
-H "Auth: at_xxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{"user_id": 123456789, "max_sponsors": 5}'
Python (requests)
import requests
resp = requests.post(
"https://api.trafsly.com/api/v1/get-sponsors",
headers={"Auth": "at_xxxxxxxx", "Content-Type": "application/json"},
json={"user_id": 123456789, "max_sponsors": 5},
)
data = resp.json()
if data["status"] == "ok":
# допускаем пользователя дальше
pass
else:
for sponsor in data["sponsors"]:
print(sponsor["link"])
Node.js (fetch)
const res = await fetch("https://api.trafsly.com/api/v1/get-sponsors", {
method: "POST",
headers: {
"Auth": "at_xxxxxxxx",
"Content-Type": "application/json",
},
body: JSON.stringify({ user_id: 123456789, max_sponsors: 5 }),
});
const data = await res.json();
Подтвердить подписку
Вызывайте этот эндпоинт после того, как пользователь нажал «Я подписался» в вашем боте. Trafsly проверит факт подписки через getChatMember и зачислит вознаграждение за выполненное задание на ваш баланс (если подписка реальна).
Request Body
{
"user_id": 123456789,
"ads_id": 10421
}
| Параметр | Тип | Обязательно | Описание |
|---|---|---|---|
user_id | integer | Да | Telegram ID пользователя |
ads_id | integer | Да | ID задания из /get-sponsors |
Response — успех
{
"status": "ok",
"subscribed": true,
"credited": 1.10,
"message": "Subscription confirmed"
}
Response — пользователь не подписался
{
"status": "warning",
"subscribed": false,
"message": "User is not subscribed"
}
Таргетинг
Рекламодатели могут настроить таргетинг заказов по 21 фильтру в @TrafslyBot. API автоматически фильтрует задания: пользователь получит только те, чьи фильтры совпадают с его профилем.
Как это работает
При вызове /get-sponsors передавайте данные пользователя Telegram. API сопоставит их с фильтрами каждого заказа и вернёт только подходящие задания.
user_id. Для полной фильтрации передавайте все доступные поля.
Поля для таргетинга в /get-sponsors
| Параметр | Какие фильтры использует | Пример |
|---|---|---|
language_code | Языки | "ru", "en", "uk" |
is_premium | Telegram Premium | true / false |
first_name | Наличие имени, кириллица, пол | "Иван" |
username | Наличие юзернейма | "ivan_durov" |
Дополнительные данные из профиля
Если пользователь ранее проходил через smart-link Trafsly, в его профиле могут быть:
| Поле | Фильтры |
|---|---|
| Страна / город | Геотаргетинг (Россия, Москва и т.д.) |
| Тип устройства | Смартфон / Десктоп / Планшет |
| ОС | Android / iOS / Windows / macOS |
| Возраст аккаунта | Минимальный возраст (2-9 лет) |
| Рейтинг | Минимальный уровень (1-10) |
Эти данные собираются автоматически и используются при фильтрации, если доступны. SDK-боту не нужно их передавать.
Категории фильтров
География
- Языки интерфейса
- Страна (с коэффициентом)
- Город (с коэффициентом)
Профиль
- Возраст пользователя (с коэффициентом)
- Пол (эвристика по имени)
- Возраст аккаунта (с коэффициентом)
Устройство
- Тип устройства (с коэффициентом)
- ОС (с коэффициентом)
- Telegram Premium
Наличие параметров
- Фото / Реальное фото
- Имя / Юзернейм / Био
- Аудио-описание
Настройки имени
- Русское имя
- Кириллица в имени
Качество аккаунта
- Рейтинг (с коэффициентом)
- Подарки (с коэффициентом)
Логика фильтрации
- Strict mismatch: если у пользователя есть данные и они не совпадают с фильтром - задание скрывается
- Unknown = pass: если данных нет (поле пустое) - задание показывается. Это значит, что чем больше данных передано, тем точнее выборка
- Коэффициенты: фильтры с пометкой «с коэффициентом» увеличивают цену за подписку для рекламодателя (x1.1 - x2.0), но не влияют на выплату публишеру
Пример запроса с таргетингом
curl -X POST https://api.trafsly.com/api/v1/get-sponsors \
-H "Auth: at_xxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"user_id": 123456789,
"first_name": "Иван",
"username": "ivan_durov",
"language_code": "ru",
"is_premium": true,
"max_sponsors": 5
}'
Health-check
Простой health-check. Возвращает {"status": "ok"}, если API живо. Авторизация не требуется.
curl https://api.trafsly.com/api/v1/health
Баланс
Возвращает текущий баланс владельца API-токена и список всех его ботов.
Request
Тело не обязательно. Авторизация через заголовок Auth.
Response
{
"balance": 922.05,
"hold_balance": 494.47,
"bots_info": [
{
"bot_id": 1,
"bot_username": "MyAwesomeBot",
"is_active": true
}
]
}
| Поле | Тип | Описание |
|---|---|---|
balance | number | Доступный баланс в рублях |
hold_balance | number | Сумма в холде (ещё не подтверждённые начисления) |
bots_info[] | array | Список ботов владельца токена |
Статистика
Универсальный статистический эндпоинт. Возвращает данные в зависимости от параметра action. Авторизация — через query-параметр api_token.
Query-параметры
| Параметр | Тип | Обязательно | Описание |
|---|---|---|---|
api_token | string | Да | API-токен любого вашего бота |
action | string | Нет | allbots (default), bots, allads, ads |
bot_id | integer | Нет | ID бота для action=bots |
output_format | string | Нет | json (default) или html |
action=allbots — сводка по всем ботам
{
"bots": [
{
"bot_id": 1,
"bot_username": "MyAwesomeBot",
"is_active": true,
"total_subscribers": 532,
"revenue": 585.20
}
]
}
action=bots&bot_id=1 — последние подписки в боте
{
"bot": "MyAwesomeBot",
"subscriptions": [
{
"user_id": 123456789,
"order_id": 10421,
"status": "subscribed",
"amount": 1.10,
"created_at": "2026-05-22T09:11:42+00:00"
}
]
}
action=allads — статистика своих рекламных заказов
{
"orders": [
{
"order_id": 87,
"name": "Канал «Crypto News»",
"status": "active",
"price_per_sub": 2.50,
"subscribers": 412,
"cr_pct": 38.4,
"spent": 1030.00
}
]
}
&output_format=html — API вернёт готовую таблицу для встраивания в админ-панель.
Статусы заданий
| Статус | Описание |
|---|---|
| subscribed | Пользователь подписался и подписка зачтена |
| unsubscribed | Пользователь не подписан (никогда или отписался) |
| notgetted | Подписка не была засчитана (повторный заход уже учтённого юзера, антифрод) |
| hold | Подписка в холде, ждёт подтверждения внешним провайдером |
Ошибки
API возвращает стандартные HTTP-коды. Ответ при ошибке — JSON с полем detail.
| HTTP | detail | Описание |
|---|---|---|
| 400 | Bad Request | Неверный формат запроса |
| 401 | Invalid or inactive Bot API Key | Неверный или отключённый API-токен |
| 404 | Bot not found | Бот / задание / пользователь не найдены |
| 422 | Validation error | Pydantic-валидация полей не прошла |
| 429 | Too Many Requests | Слишком много запросов — снизьте частоту |
| 500 | Internal Server Error | Внутренняя ошибка сервера, попробуйте позже |
Пример ошибки
HTTP/1.1 401 Unauthorized
Content-Type: application/json
{ "detail": "Invalid or inactive Bot API Key" }
Логика работы
Базовый сценарий встраивания обязательной подписки Trafsly в свой Telegram-бот:
/get-sponsors/confirm-subscriptionЧто дальше
- Получите API-токен в @TrafslyBot → Мои боты.
- Реализуйте два эндпоинта: /get-sponsors на старте бота и /confirm-subscription на кнопке «Я подписался».
- Следите за балансом через /get-balance или в кабинете @TrafslyBot.
- Если что-то не работает — канал Trafsly или напишите в поддержку из кабинета.