Управление пользователям

API пользователей бота

Публичная документация методов управления пользователями бота: список и просмотр, баланс, бан, удаление, рефералы.

Все методы — POST с телом JSON.


Авторизация

ПараметрГдеОбязательностьОписание
bot_idтелодаID бота в BOT-T
token или botTokenquery или телода*Токен бота
secretKeyquery или телода*Секретный ключ бота (вместо токена)

* Достаточно либо token / botToken, либо secretKey.

Content-Type: application/json
https://api.bot-t.com

Формат ответа:

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

Всегда проверяйте result === true перед использованием data.

Лимит: 120 запросов в минуту с одного IP.


Список методов

МетодURLНазначение
indexPOST /v1/bot/user/indexСписок пользователей
countPOST /v1/bot/user/countКоличество по тем же фильтрам
viewPOST /v1/bot/user/viewОдин пользователь по ID в боте
view-by-telegram-idPOST /v1/bot/user/view-by-telegram-idОдин пользователь по Telegram ID
view-by-user-idPOST /v1/bot/user/view-by-user-idОдин пользователь по системному ID
add-balancePOST /v1/bot/user/add-balanceНачислить баланс
subtract-balancePOST /v1/bot/user/subtract-balanceСписать баланс
zero-balancePOST /v1/bot/user/zero-balanceОбнулить баланс
banPOST /v1/bot/user/banЗабанить или разбанить
deletePOST /v1/bot/user/deleteУдалить пользователя
set-refPOST /v1/bot/user/set-refНазначить реферера
zero-refPOST /v1/bot/user/zero-refСбросить реферера
referralsPOST /v1/bot/user/referralsСписок рефералов
chats-channels-listPOST /v1/bot/user/chats-channels-listЧаты и каналы бота

Идентификаторы

В разных методах одно и то же имя поля означает разное.

ПолеГде используетсяЧто это
user_idview, add-balance, subtract-balance, ban, referralsID пользователя в боте — поле id в ответе
user_idindex, count, view-by-user-idСистемный ID — поле user.id в ответе
telegram_idindex, count, view-by-telegram-idTelegram ID — поле user.telegram_id
idban (массово), delete, zero-balance, zero-ref, set-refID пользователя в боте. Можно передать массив

Как получить нужный ID:

  1. Найти пользователя через view-by-telegram-id.
  2. Взять data.id — это ID в боте для баланса, бана, рефералов.
  3. data.user.id — системный ID, только для фильтра index / count и для view-by-user-id.

Объект пользователя

{
  "id": 123,
  "bot_id": 1,
  "user": {
    "id": 100500,
    "telegram_id": 182352323552,
    "username": "username",
    "first_name": "Иван",
    "last_name": "Иванов",
    "link": "<a href='tg://user?id=182352323552'>Иван</a>",
    "type": "private"
  },
  "ref": null,
  "money": 15000,
  "status": {
    "id": 1,
    "title": "Активный"
  },
  "create_at": 1716288000,
  "created_time": "2024-05-21 12:00:00",
  "update_at": 1716374400,
  "updated_time": "2024-05-22 12:00:00",
  "expectation": null,
  "secret_user_key": "k7f3a9b2c1d4e5f6"
}
ПолеОписание
idID пользователя в боте. Передавайте его в view, add-balance, subtract-balance, ban, referrals
user.idСистемный ID
user.telegram_idTelegram ID
user.typeprivate, group, supergroup или channel
moneyБаланс в минимальных единицах валюты (копейки). Для отображения: money / 100
refРеферер (user-объект) или null. Заполняется, если в боте включена реферальная программа
secret_user_keyСекрет пользователя. Нужен модулям и WebApp
created_time / updated_timeДата в часовом поясе бота
create_at / update_atUnix-время

В ответах view, view-by-telegram-id и view-by-user-id объект полный. В index, referrals и после операций с балансом — тот же набор полей, без дополнительных вложений.


Статусы пользователя

Поле status в фильтрах — массив чисел.

IDОписание
1Активный
2Неактивный
3Заблокирован
4Менеджер
5Не верифицирован
6Доверенный

POST /v1/bot/user/index

Список пользователей с пагинацией и фильтрами.

ПолеТипПо умолчаниюОписание
bot_idintegerID бота, обязательно
limitinteger25Записей на страницу, максимум 500
offsetinteger0Сколько записей пропустить
statusinteger[]Фильтр по статусам
sort_idstringDESCСортировка по id: ASC или DESC
sort_telegram_idstringСортировка по Telegram ID
sort_created_timestringСортировка по дате создания
sort_updated_timestringСортировка по дате обновления
sort_balancestringСортировка по балансу
idintegerID пользователя в боте
ref_idintegerСистемный ID реферера
created_time_startstringНачало периода создания (часовой пояс бота)
created_time_endstringКонец периода создания
updated_time_startstringНачало периода обновления
updated_time_endstringКонец периода обновления
min_balancenumberМинимальный баланс в основных единицах (не в копейках)
max_balancenumberМаксимальный баланс в основных единицах
user_idintegerСистемный ID
typeintegerТип Telegram-чата
telegram_idintegerTelegram ID

Если указано несколько sort_*, применяется последний переданный. По умолчанию: id DESC.

{
  "bot_id": 1,
  "status": [1],
  "limit": 100,
  "offset": 0
}
{
  "result": true,
  "data": [
    {
      "id": 123,
      "bot_id": 1,
      "user": { "id": 100500, "telegram_id": 182352323552 },
      "money": 0,
      "status": { "id": 1, "title": "Активный" }
    }
  ]
}

Примеры фильтров

Баланс от 100 до 1000:

{
  "bot_id": 1,
  "min_balance": 100,
  "max_balance": 1000,
  "limit": 500,
  "offset": 0
}

Зарегистрированные за период:

{
  "bot_id": 1,
  "created_time_start": "2024-01-01 00:00:00",
  "created_time_end": "2024-12-31 23:59:59",
  "sort_created_time": "ASC"
}

Конкретный Telegram ID:

{
  "bot_id": 1,
  "telegram_id": 182352323552
}

POST /v1/bot/user/count

Те же фильтры, что у index, но без limit, offset и сортировки.

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

data — строка с числом.

Чтобы выгрузить всех пользователей:

  1. Вызвать count с нужными фильтрами.
  2. В цикле вызывать index с limit=500 и увеличивать offset.
  3. Остановиться, когда страница пустая или offset >= count.

POST /v1/bot/user/view

Один пользователь по ID в боте.

ПолеТипОбяз.Описание
bot_idintegerдаID бота
user_idintegerдаID пользователя в боте (id из списка)
{ "bot_id": 1, "user_id": 123 }

Если пользователя нет в этом боте: user not found.


POST /v1/bot/user/view-by-telegram-id

ПолеТипОбяз.Описание
bot_idintegerдаID бота
telegram_idintegerдаTelegram ID
{ "bot_id": 1, "telegram_id": 182352323552 }

POST /v1/bot/user/view-by-user-id

ПолеТипОбяз.Описание
bot_idintegerдаID бота
user_idintegerдаСистемный ID (user.id)
{ "bot_id": 1, "user_id": 100500 }

Баланс

Сумма в запросах add-balance и subtract-balance — в основных единицах валюты (рубли, доллары).
В ответе money — в минимальных единицах (копейки). 10.5 в запросе увеличивает money на 1050.

Каждая операция пишется в историю пополнений. Повтор с тем же operation_id не меняет баланс повторно.


POST /v1/bot/user/add-balance

Начисляет сумму. Операция сразу считается выполненной.

ПолеТипОбяз.Описание
bot_idintegerдаID бота
user_idintegerдаID пользователя в боте
sumnumberдаСумма в основных единицах, больше 0. Например 10.5
commentstringнетКомментарий в истории. По умолчанию: Пополнение баланса через API
isNoticebooleanнетОтправить штатные уведомления о пополнении (пользователю и админам, если они настроены в боте). По умолчанию true
isSendCommentbooleanнетОтправить пользователю текст comment отдельным сообщением в бот. По умолчанию true
operation_idstringнетКлюч идемпотентности, до 64 символов

Уведомления

ПараметрПо умолчаниюЧто делает
isNoticetrueШлёт сообщения о успешном начислении, если они заданы в настройках пополнения бота. При false баланс и запись в истории создаются, эти сообщения не уходят
isSendCommenttrueОтдельно шлёт пользователю текст comment

Чтобы изменить баланс без сообщений пользователю, передайте оба флага false.

{
  "bot_id": 12,
  "user_id": 88,
  "sum": 100,
  "comment": "Компенсация",
  "isNotice": false,
  "isSendComment": false,
  "operation_id": "bonus-88-20260910"
}

В ответе — объект пользователя. money — баланс после операции.

{
  "result": true,
  "data": {
    "id": 88,
    "bot_id": 12,
    "money": 11500,
    "user": { "id": 50, "telegram_id": 182352323552 }
  }
}
СообщениеПричина
user_id not foundНе передан user_id
user not foundПользователь не из этого бота или не передана sum
sum should have been more 0Сумма ≤ 0
operation_id is too longКлюч длиннее 64 символов

POST /v1/bot/user/subtract-balance

Списывает сумму. Если средств меньше, чем sum, баланс не меняется.

ПолеТипОбяз.Описание
bot_idintegerдаID бота
user_idintegerдаID пользователя в боте
sumnumberдаСумма в основных единицах, больше 0
commentstringнетКомментарий. К тексту автоматически добавляется пометка (API)
operation_idstringнетКлюч идемпотентности, до 64 символов

У списания нет isNotice и isSendComment. Штатное уведомление о пополнении на списание не отправляется.

{
  "bot_id": 12,
  "user_id": 88,
  "sum": 10.5,
  "comment": "Оплата услуги",
  "operation_id": "svc-100"
}
СообщениеПричина
user_id not foundНе передан user_id
user not foundПользователь не из этого бота
sum should have been more 0Сумма ≤ 0
У Вас закончился баланс в боте. Пополните его!Недостаточно средств
operation_id is too longКлюч длиннее 64 символов

POST /v1/bot/user/zero-balance

Списывает весь текущий баланс. operation_id не поддерживается.

ПолеТипОбяз.Описание
bot_idintegerдаID бота
idinteger или массивдаОдин ID в боте или несколько
  • Один ID — в ответе объект пользователя.
  • Массив — в ответе "1".
  • Если баланс уже 0, операция не создаётся.
{ "bot_id": 12, "id": 88 }
{ "bot_id": 12, "id": [88, 89, 90] }

POST /v1/bot/user/ban

Переключает бан: заблокированный становится активным, любой другой статус — заблокированным.

ПолеТипОбяз.Описание
bot_idintegerдаID бота
user_idintegerда*Один ID в боте. В ответе — объект пользователя
idinteger или массивда*Массовый режим, если user_id не передан. В ответе "1"

* Нужен либо user_id, либо id.

{ "bot_id": 12, "user_id": 88 }
{ "bot_id": 12, "id": [88, 89] }

POST /v1/bot/user/delete

Удаляет пользователя бота. Операция необратима.

ПолеТипОбяз.Описание
bot_idintegerдаID бота
idinteger или массивдаОдин ID в боте или несколько

В ответе всегда "1".

{ "bot_id": 12, "id": 88 }
{ "bot_id": 12, "id": [88, 89, 90] }

POST /v1/bot/user/set-ref

Назначает реферера. Оба ID — пользователи в боте.

ПолеТипОбяз.Описание
bot_idintegerдаID бота
idintegerдаКому назначаем реферера
ref_idintegerдаКто пригласил

Пользователь не может быть реферером сам себе. Оба должны принадлежать этому боту.

{ "bot_id": 12, "id": 88, "ref_id": 10 }

В ответе — объект пользователя с обновлённым ref.

СообщениеПричина
id и ref_id обязательныНе переданы поля
user not foundПользователь id не из этого бота
referrer not found in this botРеферер не из этого бота
Пользователь не может быть реферером сам себеid и ref_id совпадают

POST /v1/bot/user/zero-ref

Сбрасывает реферера.

ПолеТипОбяз.Описание
bot_idintegerдаID бота
idinteger или массивдаОдин ID в боте или несколько
  • Один ID — в ответе объект пользователя.
  • Массив — в ответе "1".
  • Если реферера уже нет, ничего не меняется.
{ "bot_id": 12, "id": 88 }

POST /v1/bot/user/referrals

Список пользователей, у которых указанный пользователь — реферер.

ПолеТипПо умолчаниюОписание
bot_idintegerID бота, обязательно
user_idintegerID пригласившего в боте, обязательно
limitinteger5Записей на страницу, максимум 50
offsetinteger0Сдвиг

Сортировка: новые сверху (id DESC).

{ "bot_id": 12, "user_id": 88, "limit": 50, "offset": 0 }

В ответе — массив объектов пользователя.


POST /v1/bot/user/chats-channels-list

Чаты и каналы, привязанные к боту. Не личные пользователи.

{ "bot_id": 12 }
{
  "result": true,
  "data": {
    "-1001234567890": "Название чата (@username) #-1001234567890"
  }
}

Ключ — Telegram ID чата или канала, значение — подпись.


Идемпотентность баланса

operation_id есть только у add-balance и subtract-balance.

  • Повтор с тем же ключом в том же боте не меняет баланс второй раз.
  • Без ключа каждый запрос списывает или начисляет заново.
  • При timeout повторяйте запрос с тем же operation_id.
  • Максимум 64 символа.

Типичные ошибки

СообщениеПричина
bot_id not foundНе передан bot_id
token not foundНет token / botToken и нет secretKey
token is not validНеверный токен
secretKey is not validНеверный secretKey
user_id not foundНе передан user_id
user not foundПользователь не найден в этом боте
id not foundНе передан id
telegram_id not foundНе передан telegram_id
sortAmount should be ASC or DESCНеверное значение sort_*

Примеры кода

Замените константы на свои значения.

API_BASE   = https://api.bot-t.com
BOT_ID     = 1
BOT_TOKEN  = 123456789:ABCdefGHI...

PHP

<?php

const API_BASE = 'https://api.bot-t.com';
const BOT_ID = 1;
const BOT_TOKEN = '123456789:ABCdefGHI...';

function botUserRequest(string $action, array $body): array
{
    $url = API_BASE . '/v1/bot/user/' . $action . '?token=' . urlencode(BOT_TOKEN);

    $ch = curl_init($url);
    curl_setopt_array($ch, [
        CURLOPT_POST => true,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
        CURLOPT_POSTFIELDS => json_encode(array_merge(['bot_id' => BOT_ID], $body)),
    ]);

    $response = curl_exec($ch);
    curl_close($ch);

    $data = json_decode($response, true);
    if (!is_array($data) || ($data['result'] ?? false) !== true) {
        throw new RuntimeException($data['message'] ?? 'API error');
    }

    return $data['data'];
}

function fetchAllUsers(array $filters = []): array
{
    $limit = 500;
    $offset = 0;
    $all = [];

    do {
        $page = botUserRequest('index', array_merge($filters, [
            'limit' => $limit,
            'offset' => $offset,
        ]));
        if (empty($page)) {
            break;
        }
        $all = array_merge($all, $page);
        $offset += $limit;
    } while (count($page) === $limit);

    return $all;
}

$allActive = fetchAllUsers(['status' => [1]]);

$one = botUserRequest('view-by-telegram-id', ['telegram_id' => 182352323552]);

botUserRequest('add-balance', [
    'user_id' => $one['id'],
    'sum' => 100,
    'comment' => 'Компенсация',
    'isNotice' => false,
    'isSendComment' => false,
    'operation_id' => 'bonus-' . $one['id'],
]);

botUserRequest('subtract-balance', [
    'user_id' => $one['id'],
    'sum' => 10.5,
    'comment' => 'Оплата услуги',
    'operation_id' => 'pay-' . $one['id'],
]);

JavaScript (Node.js)

const API_BASE = 'https://api.bot-t.com';
const BOT_ID = 1;
const BOT_TOKEN = '123456789:ABCdefGHI...';

async function botUserRequest(action, body = {}) {
  const url = `${API_BASE}/v1/bot/user/${action}?token=${encodeURIComponent(BOT_TOKEN)}`;

  const response = await fetch(url, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ bot_id: BOT_ID, ...body }),
  });

  const json = await response.json();
  if (!json.result) {
    throw new Error(json.message || 'API error');
  }
  return json.data;
}

const user = await botUserRequest('view-by-telegram-id', { telegram_id: 182352323552 });

await botUserRequest('add-balance', {
  user_id: user.id,
  sum: 100,
  comment: 'Компенсация',
  isNotice: false,
  isSendComment: false,
  operation_id: `bonus-${user.id}`,
});

Токен бота не храните в клиентском JS — вызывайте API с сервера.

Python 3

import requests

API_BASE = 'https://api.bot-t.com'
BOT_ID = 1
BOT_TOKEN = '123456789:ABCdefGHI...'


def bot_user_request(action: str, body: dict = None):
    url = f'{API_BASE}/v1/bot/user/{action}'
    response = requests.post(
        url,
        params={'token': BOT_TOKEN},
        json={'bot_id': BOT_ID, **(body or {})},
        headers={'Content-Type': 'application/json'},
        timeout=30,
    )
    response.raise_for_status()
    data = response.json()
    if not data.get('result'):
        raise RuntimeError(data.get('message', 'API error'))
    return data['data']


user = bot_user_request('view-by-telegram-id', {'telegram_id': 182352323552})

bot_user_request('add-balance', {
    'user_id': user['id'],
    'sum': 100,
    'comment': 'Компенсация',
    'isNotice': False,
    'isSendComment': False,
    'operation_id': f"bonus-{user['id']}",
})

Авторизация через secretKey

Вместо токена можно передать секретный ключ бота:

POST /v1/bot/user/index?secretKey=YOUR_SECRET_KEY