API
Автоматическая выгрузка статистики MAX-канала через API БОТИКИ.
🔌 API выгрузки статистики MAX-канала
API позволяет получать аналитику MAX-канала за выбранный период с фильтрацией по пользователям, подписке, ссылкам и UTM-меткам. Результат формируется в CSV для дальнейшей обработки в CRM, BI-сервисах и других внешних системах.
Выгрузка выполняется асинхронно:
- Создайте заявку.
- Проверяйте её статус.
- Получите ссылки и скачайте все части выгрузки.
🔑 Получение API-токена
Токен показывается только один раз — сразу после создания. До нажатия «Создать токен» подготовьте безопасное место для его сохранения. Если закрыть окно, восстановить токен нельзя: потребуется выпустить новый.
Перейдите: MAX → БОТИКА → Меню → API-токены.
Нажмите «Создать токен» и задайте понятное название, например «CRM-интеграция».
Скопируйте и сохраните токен сразу после выпуска.
Токен привязан к одному каналу, поэтому channel_id передавать не нужно. Он действует 1 год с момента выпуска. После истечения срока API отвечает 401 — выпустите новый токен заранее.
Токен можно отозвать или перевыпустить в панели управления. При перевыпуске старый токен удаляется и прекращает работать сразу после выдачи нового. Планируйте замену на техническое окно: получите новый токен и сразу пропишите его в интеграции.
🌐 Базовый адрес и заголовки
https://{botica-api-domain}/api/stat/v1Все запросы и ответы используют UTF-8. Во всех запросах передавайте:
Accept: application/json
Authorization: Bearer <ваш-токен>Для JSON-тела также требуется:
Content-Type: application/jsonНедействительный, отозванный или истёкший токен приводит к ответу 401 Unauthorized.
Запрос количества подписчиков
Возвращает количество подписчиков канала.
POST /api/stat/v1/runtime/participantsСтруктура ответа (integer — целое число):
{
"participants": integer
}📤 1. Создание заявки
POST /exportsТело запроса
{
"type": "export_post_link_visits",
"period_from": 1735689600,
"period_to": 1738368000,
"filters": {
"subscribed": true,
"utm_source": "yandex"
}
}| Поле | Тип | Обяз. | Описание |
|---|---|---|---|
| type | string | да | Тип выгрузки из таблицы ниже |
| period_from | int, Unix-время в секундах | да | Начало периода |
| period_to | int, Unix-время в секундах | да | Конец периода |
| filters | object | нет | Фильтры, зависящие от type |
Границы периода включаются в выборку. Если начало или конец периода не переданы, API вернёт 422.
Типы выгрузок и их параметры
| type | Что выгружает |
|---|---|
| export_post_link_visits | Переходы по ссылкам на посты |
| export_webapp_visits | Переходы с лендинг-вебапп |
| export_subscribers | Подписчики канала |
Фильтры передаются в объекте filters. Недопустимый для выбранного типа фильтр приводит к 422.
| Фильтр | Тип | post_link | webapp | subscribers | Описание |
|---|---|---|---|---|---|
| max_id | int | ✓ | ✓ | ✓ | MAX ID пользователя |
| yandex_client_id | string | — | ✓ | — | Yandex ClientID |
| post_link_id | int | ✓ | — | — | ID ссылки на пост |
| subscribed | bool | ✓ | ✓ | ✓ | true — подписанные, false — неподписанные |
| utm_source | string | ✓ | ✓ | — | Точное совпадение |
| utm_medium | string | ✓ | ✓ | — | Точное совпадение |
| utm_campaign | string | ✓ | ✓ | — | Точное совпадение |
| utm_content | string | ✓ | ✓ | — | Точное совпадение |
| utm_term | string | ✓ | ✓ | — | Точное совпадение |
Строковые фильтры — не длиннее 255 символов. Период задаётся отдельно, не внутри filters.
Ответ 202 Accepted
{
"request_id": "0f8c1e2a-3b4c-4d5e-9f01-2a3b4c5d6e7f",
"status": "pending"
}Сохраните request_id. Если выгрузка этого типа уже выполняется для канала, API вернёт 429 вместе с идентификатором текущей заявки:
{
"request_id": "0f8c1e2a-3b4c-4d5e-9f01-2a3b4c5d6e7f",
"status": "processing",
"message": "Export of this type is already in progress for the channel."
}Дождитесь завершения текущей заявки. В этом ответе status содержит pending или processing. Заголовка Retry-After здесь нет: он передаётся только при превышении лимита частоты.
Повторная заявка с теми же типом, периодом и фильтрами может выполниться почти мгновенно — результат предыдущей выгрузки некоторое время переиспользуется.
⏳ 2. Проверка статуса
GET /exports/{request_id}Проверяйте статус каждые 5–10 секунд, пока он не станет completed или failed.
| Статус | Описание |
|---|---|
| pending | Заявка принята и ожидает обработки |
| processing | Файлы формируются |
| completed | Файлы готовы; ссылки находятся в files |
| failed | Произошла ошибка |
Ответ во время обработки:
{
"request_id": "0f8c1e2a-3b4c-4d5e-9f01-2a3b4c5d6e7f",
"type": "export_post_link_visits",
"status": "processing"
}Ответ после завершения:
{
"request_id": "0f8c1e2a-3b4c-4d5e-9f01-2a3b4c5d6e7f",
"type": "export_post_link_visits",
"status": "completed",
"files": [
{
"name": "postlink_click_stat_01-01-2026_31-01-2026_777_part1.csv",
"size": 12345678,
"download": "https://{botica-api-domain}/api/stat/v1/exports/0f8c1e2a-.../download/1"
}
],
"expires_at": 1738454400
}- files — все части выгрузки, каждую нужно скачать;
- size — размер в байтах; 0 означает, что файл удалён;
- expires_at — Unix-время, после которого выгрузка устаревает.
Ответ при ошибке:
{
"request_id": "0f8c1e2a-3b4c-4d5e-9f01-2a3b4c5d6e7f",
"type": "export_post_link_visits",
"status": "failed",
"error": "Описание ошибки"
}📥 3. Скачивание файлов
Файл не приходит в ответе на проверку статуса. При completed API возвращает массив files с готовыми ссылками download.
Используйте каждую ссылку download из ответа — не собирайте URL вручную. Заголовок Authorization обязателен.
GET /exports/{request_id}/download/{part}- part — номер части, начиная с 1;
- ответ содержит CSV с Content-Type: text/csv; charset=UTF-8;
- отсутствующая часть возвращает 404 Not Found;
- удалённый файл возвращает 410 Gone.
🗄️ Хранение и формат файлов
- Файл доступен по умолчанию 1 час с момента готовности; точное время указано в expires_at.
- Файлы удаляются фоновой чисткой, поэтому ссылка может работать некоторое время после expires_at. Гарантий доступности после этого момента нет — скачивайте файлы сразу после completed.
- После удаления скачивание отвечает 410 Gone, а size в статусе становится 0. В этом случае создайте новую заявку.
- Кодировка CSV — UTF-8 с BOM, разделитель — точка с запятой, перенос строк — CRLF.
- Значения при необходимости заключаются в двойные кавычки.
- Первая строка каждого файла содержит заголовки колонок, которые повторяются в каждой части.
- Один файл содержит до 100 000 строк данных.
- Если часть одна, суффикс part в имя не добавляется. Большая выгрузка получает суффиксы part1, part2 и далее. Обрабатывайте весь массив files, а не имена файлов.
Колонки export_post_link_visits
Дата, Время, Подписка, MaxID, first_name, last_name, Ссылка на пост, Название поста, utm_source, utm_medium, utm_campaign, utm_content, utm_term, Подписан/Не подписан, Дата подписки, Время подписки, Дата отписки, Время отписки.
Колонки export_webapp_visits
Дата, Время, Подписка, MaxID, Yandex ClientID, first_name, last_name, utm_source, utm_medium, utm_campaign, utm_content, utm_term, Пост, Подписан/Не подписан, Дата подписки, Время подписки, Дата отписки, Время отписки.
Колонки export_subscribers
max_id, first_name, last_name, utm_source, utm_medium, utm_campaign, utm_content, utm_term, Подписан/Не подписан, Дата подписки, Время подписки, Дата отписки, Время отписки, Количество дней в канале.
⚠️ Ограничения по частоте
Лимиты считаются по токену:
| Действие | Лимит |
|---|---|
| Создание заявок — POST /exports | 5 в минуту |
| Проверка статуса и скачивание — GET | 60 в минуту |
GET-запросы используют общий счётчик. При превышении API отвечает 429 Too Many Requests с заголовком Retry-After.
❌ Коды ответов
| Код | Значение |
|---|---|
| 202 Accepted | Заявка создана |
| 200 OK | Успешный статус или скачивание файла |
| 401 Unauthorized | Токен отсутствует, отозван или истёк |
| 403 Forbidden | Не хватает прав на выгрузку |
| 404 Not Found | Заявка не найдена, принадлежит другому каналу или часть файла отсутствует |
| 410 Gone | Файл удалён с диска |
| 422 Unprocessable Entity | Ошибка типа, периода или фильтра |
| 429 Too Many Requests | Превышен лимит частоты или по каналу и типу уже выполняется выгрузка |
Ошибка валидации:
{
"errors": {
"type": ["The selected type is invalid."]
}
}🧪 Пример полного цикла
Создание заявки:
curl -X POST https://{botica-api-domain}/api/stat/v1/exports \
-H "Authorization: Bearer <ваш-токен>" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"type": "export_post_link_visits",
"period_from": 1735689600,
"period_to": 1738368000,
"filters": { "subscribed": true, "utm_source": "yandex" }
}'Ответ:
{
"request_id": "0f8c1e2a-3b4c-4d5e-9f01-2a3b4c5d6e7f",
"status": "pending"
}Проверка статуса:
curl https://{botica-api-domain}/api/stat/v1/exports/0f8c1e2a-3b4c-4d5e-9f01-2a3b4c5d6e7f \
-H "Authorization: Bearer <ваш-токен>" \
-H "Accept: application/json"После completed выполните запрос для каждой ссылки download:
curl -OJ https://{botica-api-domain}/api/stat/v1/exports/0f8c1e2a-3b4c-4d5e-9f01-2a3b4c5d6e7f/download/1 \
-H "Authorization: Bearer <ваш-токен>" \
-H "Accept: application/json"