Кастомные поля пользователя: город, источник, отказ от рассылки и любые свои ключи.
Два слоя:
- Справочник ключей бота — какие атрибуты есть у бота и как они называются.
- Значения пользователя — что записано конкретному пользователю.
Авторизация
Все методы — POST с телом JSON.
| Параметр | Где | Обязательность | Описание |
|---|---|---|---|
bot_id | тело | да | ID бота в BOT-T |
token или botToken | query или тело | да* | Токен бота |
secretKey | query | да* | Секретный ключ бота (альтернатива токену) |
* Достаточно либо token/botToken, либо secretKey.
Заголовки:
Content-Type: application/json
Базовый URL:
https://api.bot-t.com
Формат ответа:
{ "result": true, "data": ... }
{ "result": false, "message": "текст ошибки" }
Всегда проверяйте result === true перед использованием data.
Лимит запросов: 120 запросов в минуту с одного IP.
Как устроены атрибуты
Атрибут — пара key → value (строки). Это отдельные поля, не статус и не баланс пользователя.
| Тип | Примеры ключей |
|---|---|
| Кастомные | city, source, любой свой ключ |
| Системные | mailing_opt_out, utm, utm_first |
Правила ключа:
- после записи ключ приводится к нижнему регистру (
City→city); - начинается с латинской буквы, дальше буквы, цифры или
_, длина 1–32; - значение — строка до 1024 символов;
nullили пустая строка удаляет значение.
Запрещены: balance, status, expectation, referral.
Системные:
| Ключ | Можно писать из API | Описание |
|---|---|---|
mailing_opt_out | да | отказ от рассылки; любое непустое значение сохраняется как "1" |
utm | нет | текущий UTM, задаётся автоматически |
utm_first | нет | первый UTM, задаётся автоматически и не перезаписывается |
Если записать кастомный ключ, которого ещё нет в справочнике, он создастся сам (название = ключ). Чтобы сразу задать своё название — сначала создайте ключ в справочнике.
Кто такой user_id
user_idВ методах значений нужен системный ID пользователя — поле user.id из ответа просмотра пользователя:
POST /v1/bot/user/view-by-telegram-idPOST /v1/bot/user/view-by-user-idPOST /v1/bot/user/view— беритеuser.id, не верхнийid
Либо передайте telegram_id вместо user_id — достаточно одного из двух.
Верхний id из ответа пользователя (ID записи в боте) сюда не подходит.
Справочник ключей бота
| Метод | URL | Назначение |
|---|---|---|
index | POST /v1/bot/user/attribute-def/index | список ключей бота |
create | POST /v1/bot/user/attribute-def/create | добавить ключ |
update | POST /v1/bot/user/attribute-def/update | переименовать (только title) |
delete | POST /v1/bot/user/attribute-def/delete | удалить ключ из справочника |
Системные ключи в справочник не входят.
POST /v1/bot/user/attribute-def/index
Тело: только bot_id.
{
"result": true,
"data": [
{ "id": 15, "bot_id": 1, "key": "city", "title": "Город" }
]
}
POST /v1/bot/user/attribute-def/create — добавить атрибут
| Поле | Тип | Описание |
|---|---|---|
bot_id | integer | ID бота |
key | string | ключ (city) |
title | string | название; если пусто — равно key |
{
"bot_id": 1,
"key": "city",
"title": "Город"
}
Ответ — созданный элемент справочника (id, bot_id, key, title).
Повторный запрос с тем же key вернёт уже существующую запись, ключ не дублируется.
POST /v1/bot/user/attribute-def/update — переименовать
Ключ (key) менять нельзя, только название.
| Поле | Тип | Описание |
|---|---|---|
bot_id | integer | ID бота |
id | integer | ID записи справочника |
title | string | новое название |
{
"bot_id": 1,
"id": 15,
"title": "Город проживания"
}
POST /v1/bot/user/attribute-def/delete — удалить атрибут из справочника
| Поле | Тип | Описание |
|---|---|---|
bot_id | integer | ID бота |
id | integer | ID записи справочника |
{
"bot_id": 1,
"id": 15
}
{ "result": true, "data": { "ok": true } }
Удаляется только справочник. Значения у пользователей остаются. Чтобы стереть значение — вызовите удаление значения.
Значения у пользователя
| Метод | URL | Назначение |
|---|---|---|
index | POST /v1/bot/user/attribute/index | прочитать все значения |
upsert | POST /v1/bot/user/attribute/upsert | добавить или изменить |
delete | POST /v1/bot/user/attribute/delete | удалить значение |
Ответ этих трёх методов одинаковый:
{
"result": true,
"data": {
"attributes": {
"city": "Москва",
"source": "ads"
},
"system_attributes": {
"mailing_opt_out": "1"
}
}
}
| Поле | Описание |
|---|---|
attributes | кастомные ключи |
system_attributes | mailing_opt_out, utm, utm_first (если заданы) |
Пустых ключей в ответе нет. Те же поля приходят при просмотре одного пользователя (view, view-by-telegram-id, view-by-user-id). В списке пользователей их нет.
POST /v1/bot/user/attribute/index — прочитать
| Поле | Тип | Описание |
|---|---|---|
bot_id | integer | ID бота |
user_id | integer | системный ID пользователя или |
telegram_id | integer | Telegram ID |
{
"bot_id": 1,
"telegram_id": 182352323552
}
POST /v1/bot/user/attribute/upsert — добавить или изменить
Один метод: нет ключа — создаст, есть — перезапишет.
| Поле | Тип | Описание |
|---|---|---|
bot_id | integer | ID бота |
user_id или telegram_id | integer | кто |
key | string | ключ |
value | string или null | значение; null или "" удаляет ключ |
Добавить или изменить город:
{
"bot_id": 1,
"telegram_id": 182352323552,
"key": "city",
"value": "Москва"
}
Отписать от рассылки:
{
"bot_id": 1,
"telegram_id": 182352323552,
"key": "mailing_opt_out",
"value": "1"
}
Вернуть в рассылку — удалите ключ.
POST /v1/bot/user/attribute/delete — удалить значение
| Поле | Тип | Описание |
|---|---|---|
bot_id | integer | ID бота |
user_id или telegram_id | integer | кто |
key | string | какой ключ |
{
"bot_id": 1,
"telegram_id": 182352323552,
"key": "city"
}
Если ключа у пользователя нет — запрос всё равно успешен, в ответе текущие значения без этого ключа.
Типичный сценарий
- Создать ключ
cityс названием «Город» (можно пропустить). - Записать город пользователю.
- Прочитать значения.
- Записать новое значение — изменить.
- Удалить значение.
- Удалить ключ из справочника бота (значения у пользователей не трогает).
Примеры кода
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 botAttrRequest(string $path, array $body): array
{
$url = API_BASE . '/v1/bot/user/' . $path . '?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'];
}
// Справочник: добавить ключ
$def = botAttrRequest('attribute-def/create', [
'key' => 'city',
'title' => 'Город',
]);
// Значение: записать / изменить
$maps = botAttrRequest('attribute/upsert', [
'telegram_id' => 182352323552,
'key' => 'city',
'value' => 'Москва',
]);
// Прочитать
$maps = botAttrRequest('attribute/index', [
'telegram_id' => 182352323552,
]);
// Удалить значение
$maps = botAttrRequest('attribute/delete', [
'telegram_id' => 182352323552,
'key' => 'city',
]);
// Удалить ключ из справочника
botAttrRequest('attribute-def/delete', ['id' => $def['id']]);
JavaScript (Node.js, fetch)
const API_BASE = 'https://api.bot-t.com';
const BOT_ID = 1;
const BOT_TOKEN = '123456789:ABCdefGHI...';
async function botAttrRequest(path, body = {}) {
const url = `${API_BASE}/v1/bot/user/${path}?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;
}
(async () => {
const def = await botAttrRequest('attribute-def/create', {
key: 'city',
title: 'Город',
});
await botAttrRequest('attribute/upsert', {
telegram_id: 182352323552,
key: 'city',
value: 'Москва',
});
const maps = await botAttrRequest('attribute/index', {
telegram_id: 182352323552,
});
console.log(maps.attributes.city);
await botAttrRequest('attribute/delete', {
telegram_id: 182352323552,
key: 'city',
});
await botAttrRequest('attribute-def/delete', { id: def.id });
})();
Токен бота не храните в браузерном JavaScript — вызывайте API с сервера.
Python 3
import requests
API_BASE = 'https://api.bot-t.com'
BOT_ID = 1
BOT_TOKEN = '123456789:ABCdefGHI...'
def bot_attr_request(path: str, body: dict = None) -> dict:
url = f'{API_BASE}/v1/bot/user/{path}'
payload = {'bot_id': BOT_ID, **(body or {})}
response = requests.post(
url,
params={'token': BOT_TOKEN},
json=payload,
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']
# Справочник
def_ = bot_attr_request('attribute-def/create', {'key': 'city', 'title': 'Город'})
# Записать / изменить
bot_attr_request('attribute/upsert', {
'telegram_id': 182352323552,
'key': 'city',
'value': 'Москва',
})
# Прочитать
maps = bot_attr_request('attribute/index', {'telegram_id': 182352323552})
print(maps['attributes'].get('city'))
# Удалить значение
bot_attr_request('attribute/delete', {
'telegram_id': 182352323552,
'key': 'city',
})
# Удалить ключ справочника
bot_attr_request('attribute-def/delete', {'id': def_['id']})
Типичные ошибки
| Сообщение | Причина |
|---|---|
bot_id not found | Нет bot_id в теле |
token not found / token is not valid | Нет или неверный токен |
secretKey is not valid | Неверный secretKey |
user_id not found | Нет ни user_id, ни telegram_id |
user not found | Пользователь не найден в этом боте |
key not found | Не передан key |
id not found | Нет id при изменении или удалении ключа справочника |
Некорректный ключ атрибута | Ключ не подходит под формат |
Этот ключ зарезервирован | balance, status, expectation, referral |
Системный атрибут нельзя изменить вручную | Попытка записать utm или utm_first |
Значение атрибута слишком длинное | Больше 1024 символов |
Название атрибута не может быть пустым | Пустой title при создании или переименовании |
Нет доступа к атрибуту | Ключ справочника принадлежит другому боту |
Важные замечания
- В этих методах
user_id— системный ID (user.idиз просмотра пользователя), не верхнийidзаписи в боте. Проще передатьtelegram_id. - Добавить и изменить значение — один метод
upsert. - Пустой
valueвupsertудаляет значение, как отдельное удаление. - Удаление ключа из справочника не чистит значения пользователей.
utmиutm_firstиз API только читаются.- Авторизация через секретный ключ:
POST /v1/bot/user/attribute/upsert?secretKey=YOUR_SECRET_KEY.