API подписок: управление доступами
Документ для внешних серверов: выдача, продление, отзыв и просмотр доступов к каналам/чатам бота подписок.
Хост: https://api.bot-t.com. Все методы — POST, тело application/json.
Бот должен быть ботом подписок. Лимит: 120 запросов в минуту с одного IP.
Авторизация
В каждом запросе: bot_id и один секрет.
| Поле | Где взять |
|---|---|
token | Токен бота из BotFather |
secretKey | Секретный ключ бота в кабинете |
Секрет — в query или в теле. Токен и секрет храните только на своём сервере.
POST https://api.bot-t.com/v1/subscriber/users/grant?token=123456:ABC
Content-Type: application/json
{ "bot_id": 1, "telegram_id": 123456789, "resource_id": 3, "tariff_id": 12 }
Ответ
{ "result": true, "data": {} }
{ "result": false, "message": "текст ошибки" }
Булевы операции часто возвращают data строкой "1". Даты без пометки — в часовом поясе бота, ГГГГ-ММ-ДД ЧЧ:ММ:СС. Допустим unix timestamp.
Идентификаторы
| Поле | Что это |
|---|---|
user_id | Внутренний ID пользователя в BOT-T (users.id), не Telegram ID |
telegram_id | Telegram ID |
resource_id | Группа ресурсов (каналы/чаты) |
tariff_id | Тариф группы |
id | ID купленной подписки (записи доступа) |
user_id в методах ниже — системный. В grant можно передать telegram_id вместо него.
Статус покупки
| Значение | Смысл |
|---|---|
| 1 | не оплачена |
| 2 | оплачена, доступ активен |
| 3 | срок истёк |
| 4 | ожидает оплаты |
Клиент
Python
import requests
API = "https://api.bot-t.com"
TOKEN = "123456:ABC"
BOT_ID = 1
def call(path, **body):
response = requests.post(
f"{API}{path}",
params={"token": TOKEN},
json={"bot_id": BOT_ID, **body},
timeout=30,
)
response.raise_for_status()
payload = response.json()
if not payload.get("result"):
raise RuntimeError(payload.get("message", "ошибка API"))
return payload["data"]
JavaScript
const API = "https://api.bot-t.com";
const TOKEN = "123456:ABC";
const BOT_ID = 1;
async function call(path, body = {}) {
const response = await fetch(`${API}${path}?token=${encodeURIComponent(TOKEN)}`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ bot_id: BOT_ID, ...body }),
});
const payload = await response.json();
if (!payload.result) {
throw new Error(payload.message || "ошибка API");
}
return payload.data;
}
Выдать доступ пользователю
POST /v1/subscriber/users/grant
Создаёт оплаченную подписку от имени администратора и отправляет приглашение в каналы/чаты группы (как ручная выдача в кабинете).
Ограничения:
- пользователь уже должен хотя бы раз написать боту (быть в боте);
- тариф должен принадлежать группе, быть обычным (не пробным);
- активный доступ на ту же группу будет закрыт и заменён новым периодом.
| Поле | Обяз. | Описание |
|---|---|---|
user_id | да* | Системный ID |
telegram_id | да* | Telegram ID (альтернатива user_id) |
resource_id | да | Группа |
tariff_id | да | Тариф этой группы |
accrue_referral_bonus | нет | 1 по умолчанию — начислить реферальный бонус; 0 — нет |
* Нужно одно из двух.
access = call(
"/v1/subscriber/users/grant",
telegram_id=123456789,
resource_id=3,
tariff_id=12,
accrue_referral_bonus=0,
)
# access["id"], access["status"] == 2, access["end_paid_at"], ...
const access = await call("/v1/subscriber/users/grant", {
telegram_id: 123456789,
resource_id: 3,
tariff_id: 12,
accrue_referral_bonus: 0,
});
data — объект покупки (см. поля ниже).
Выдать ссылку без пользователя
POST /v1/subscriber/users/issue-link
Одноразовые invite-ссылки (member_limit = 1) на все каналы/чаты группы. Срок — длительность тарифа от текущего момента (не больше 1 года — лимит Telegram). Запись подписчика не создаётся.
| Поле | Обяз. |
|---|---|
resource_id | да |
tariff_id | да (включённый, не пробный) |
{
"result": true,
"data": {
"invite": "Название: https://t.me/+…",
"expire_date": 1767225600,
"resource_id": 3,
"tariff_id": 12
}
}
Список и просмотр
Покупки по боту / группе
POST /v1/subscriber/users/index
| Поле | Обяз. | Описание |
|---|---|---|
resource_id | нет | Одна группа; без поля — все группы бота |
status | нет | Фильтр статуса |
user_id | нет | Фильтр покупателя |
tariff_id | нет | Тариф или массив |
limit | нет | По умолчанию 25, максимум 1000 |
offset | нет | По умолчанию 0 |
Количество
POST /v1/subscriber/users/count — те же фильтры, data строкой, например "128".
Покупки одного пользователя
POST /v1/subscriber/users/bot-user-index — обязателен user_id.
POST /v1/subscriber/users/bot-user-count — обязателен user_id.
Одна покупка
POST /v1/subscriber/users/view — обязателен id покупки.
Поля объекта покупки
| Поле | Описание |
|---|---|
id | ID покупки |
status | 1–4 |
user | id, telegram_id, username, first_name, last_name, … |
resource_id, resource_title | Группа |
tariff_id, tariff_title, tariff_price | Тариф |
paid_at / end_paid_at | Начало / конец доступа, unix UTC |
paid_time / end_paid_time | То же в часовом поясе бота |
is_recurrent | Автопродление |
can_edit_access_start | Можно сдвинуть дату начала |
Продлить / сдвинуть сроки
Дата окончания одной покупки
POST /v1/subscriber/users/edit-end-date
| Поле | Обяз. |
|---|---|
id | да |
end_paid_time | да — дата в TZ бота или unix |
Дата окончания у нескольких
POST /v1/subscriber/users/mass-edit-end-date
| Поле | Обяз. | Описание |
|---|---|---|
resource_id | да | Группа |
end_paid_time | да | Новая дата |
id | нет | Массив ID; без него — все активные доступы группы |
{ "result": true, "data": { "updated": 14, "message": "Обновлено записей: 14" } }
Дата начала
POST /v1/subscriber/users/edit-access-start
Только если can_edit_access_start = true (оплачено, период ещё не начался). Длительность сохраняется.
| Поле | Обяз. |
|---|---|
id | да |
paid_time | да |
Приглашения
| Метод | Назначение |
|---|---|
POST /v1/subscriber/users/invite | Бот сам отправит ссылку пользователю (id покупки) |
POST /v1/subscriber/users/generate-invite | Вернуть текст со ссылкой (data — строка) |
Ссылка не выдаётся, если срок истёк или дата начала ещё не наступила.
Подтвердить неоплаченную покупку
POST /v1/subscriber/users/success — id покупки. Отмечает оплату администратором (data = "1").
Выключить автопродление
POST /v1/subscriber/users/remove-rebill — id покупки.
Удалить доступ
POST /v1/subscriber/users/delete
| Поле | Обяз. | Описание |
|---|---|---|
id | да | ID или массив ID |
Пользователя убирают из ресурса. data = "1".
call("/v1/subscriber/users/delete", id=[501, 502])
Типовые сценарии
CRM выдала оплату → открыть канал
- Узнать
resource_idиtariff_id(методыresource/index,tariff/indexили из кабинета). grantсtelegram_id(илиuser_id).- При необходимости дождаться вебхука
subscription.status_changedсоstatus=2.
Отозвать доступ
delete по id покупки. Вебхук при удалении не отправляется — синхронизируйте у себя сами.
Продлить без новой оплаты
edit-end-date или mass-edit-end-date.
Разовая ссылка без учёта пользователя
issue-link — подходит для офлайн-оплаты / менеджерской выдачи «на руки».
Сводка методов доступа
Ниже — краткий справочник. Во всех запросах обязательны bot_id и секрет (token или secretKey).
POST /v1/subscriber/users/grant — выдать доступ
POST /v1/subscriber/users/grant — выдать доступСоздаёт оплаченную подписку от имени администратора и отправляет invite в каналы/чаты группы. Пользователь уже должен быть в боте. Пробный тариф выдать нельзя. Активный доступ на ту же группу закрывается новым периодом.
| Поле | Обяз. | Описание |
|---|---|---|
user_id | да* | Системный ID пользователя |
telegram_id | да* | Telegram ID (вместо user_id) |
resource_id | да | Группа ресурсов |
tariff_id | да | Обычный тариф этой группы |
accrue_referral_bonus | нет | 1 (по умолчанию) — реф. бонус; 0 — нет |
data — объект покупки (status = 2).
POST /v1/subscriber/users/issue-link — ссылка без пользователя
POST /v1/subscriber/users/issue-link — ссылка без пользователяОдноразовые invite-ссылки (member_limit = 1) на все чаты группы. Срок = длительность тарифа от сейчас (не больше 1 года). Запись подписчика не создаётся. Тариф должен быть включён и не пробный.
| Поле | Обяз. |
|---|---|
resource_id | да |
tariff_id | да |
data: invite (строка со ссылками), expire_date (unix), resource_id, tariff_id.
POST /v1/subscriber/users/index — список покупок
POST /v1/subscriber/users/index — список покупокПагинированный список купленных доступов бота. Без resource_id — по всем группам.
| Поле | Обяз. | Описание |
|---|---|---|
resource_id | нет | Одна группа |
status | нет | 1–4 |
user_id | нет | Покупатель |
tariff_id | нет | Тариф или массив |
id | нет | Конкретная покупка |
paid_time_start / paid_time_end | нет | Период начала доступа |
end_paid_time_start / end_paid_time_end | нет | Период окончания |
created_time_start / created_time_end | нет | Период создания записи |
paid_at / end_paid_at / notification_at | нет | Сортировка: ASC или DESC |
limit | нет | По умолчанию 25, максимум 1000 |
offset | нет | По умолчанию 0 |
data — массив объектов покупки.
POST /v1/subscriber/users/count — количество покупок
POST /v1/subscriber/users/count — количество покупокТе же фильтры, что у index (без limit / offset / сортировки).
data — число строкой, например "128".
POST /v1/subscriber/users/bot-user-index — покупки одного пользователя
POST /v1/subscriber/users/bot-user-index — покупки одного пользователяВсе доступы пользователя по всем группам бота.
| Поле | Обяз. | Описание |
|---|---|---|
user_id | да | Системный ID |
фильтры / limit / offset | нет | Как у index |
data — массив объектов покупки.
POST /v1/subscriber/users/bot-user-count — сколько покупок у пользователя
POST /v1/subscriber/users/bot-user-count — сколько покупок у пользователя| Поле | Обяз. |
|---|---|
user_id | да |
| фильтры | нет |
data — число строкой.
POST /v1/subscriber/users/view — одна покупка
POST /v1/subscriber/users/view — одна покупка| Поле | Обяз. |
|---|---|
id | да — ID покупки |
data — объект покупки. Чужую покупку (другого бота) вернуть нельзя.
POST /v1/subscriber/users/success — подтвердить оплату
POST /v1/subscriber/users/success — подтвердить оплатуОтмечает неоплаченную покупку оплаченной администратором (как ручное подтверждение в кабинете): открывает доступ и шлёт приглашение.
| Поле | Обяз. |
|---|---|
id | да — ID покупки |
data — "1".
POST /v1/subscriber/users/invite — отправить приглашение
POST /v1/subscriber/users/invite — отправить приглашениеБот сам пишет пользователю сообщение со ссылками в каналы/чаты по уже выданной покупке.
| Поле | Обяз. |
|---|---|
id | да — ID покупки |
data — "ok". Не сработает, если срок истёк или дата начала ещё не наступила.
POST /v1/subscriber/users/generate-invite — получить ссылку
POST /v1/subscriber/users/generate-invite — получить ссылкуТо же приглашение, но без отправки пользователю: ссылка возвращается вам.
| Поле | Обяз. |
|---|---|
id | да — ID покупки |
data — строка со ссылками. Те же ограничения по сроку, что у invite.
POST /v1/subscriber/users/edit-end-date — дата окончания одной покупки
POST /v1/subscriber/users/edit-end-date — дата окончания одной покупкиСтавит новую дату конца доступа. Если дата ещё в будущем — пересчитывается ближайшее уведомление.
| Поле | Обяз. | Описание |
|---|---|---|
id | да | ID покупки |
end_paid_time | да | Дата в TZ бота или unix timestamp |
data — обновлённый объект покупки.
POST /v1/subscriber/users/mass-edit-end-date — дата окончания у нескольких
POST /v1/subscriber/users/mass-edit-end-date — дата окончания у нескольких| Поле | Обяз. | Описание |
|---|---|---|
resource_id | да | Группа |
end_paid_time | да | Новая дата (TZ бота или unix) |
id | нет | Массив ID; без него — все активные (status = 2) доступы группы |
data: { "updated": N, "message": "Обновлено записей: N" }.
POST /v1/subscriber/users/edit-access-start — дата начала
POST /v1/subscriber/users/edit-access-start — дата началаСдвигает начало оплаченного периода. Доступно только если can_edit_access_start = true (оплачено и paid_at ещё в будущем). Длительность сохраняется, конец едет на ту же величину.
| Поле | Обяз. | Описание |
|---|---|---|
id | да | ID покупки |
paid_time | да | Новая дата начала (TZ бота или unix) |
data — обновлённый объект покупки.
POST /v1/subscriber/users/remove-rebill — выключить автопродление
POST /v1/subscriber/users/remove-rebill — выключить автопродлениеСнимает привязку рекуррентного платежа у покупки. Текущий период доступа не трогает.
| Поле | Обяз. |
|---|---|
id | да — ID покупки |
data — "1".
POST /v1/subscriber/users/rebuild-notification — пересчитать уведомления
POST /v1/subscriber/users/rebuild-notification — пересчитать уведомленияПересчитывает и сохраняет дату ближайшего уведомления об окончании. Неактивные записи пропускаются.
| Поле | Обяз. | Описание |
|---|---|---|
id | да | ID покупки или массив ID |
data — "1".
POST /v1/subscriber/users/delete — удалить доступ
POST /v1/subscriber/users/delete — удалить доступУбирает пользователя из ресурса и удаляет запись(и) покупки. Вебхук при удалении не уходит.
| Поле | Обяз. | Описание |
|---|---|---|
id | да | ID покупки или массив ID |
data — "1".