Начало
Обзор
Документация для разработчиков Min (MinChat): REST API, realtime-события и Bot API, совместимый с Telegram.
Min — мессенджер с веб-, десктоп- и Android-клиентами. Всё, что делают официальные клиенты, идёт через описанный здесь HTTP API: JSON REST API под /api, Pusher-совместимый WebSocket для realtime-событий и отдельный Bot API, совместимый с Telegram.
| Что | Значение |
|---|---|
| Базовый URL REST | https://minchatapp.com/api |
| Bot API | https://minchatapp.com/bot<token>/<method> |
| Realtime | Reverb (протокол Pusher) — параметры из GET /api/broadcasting/client-config |
| Формат | JSON (application/json); загрузка файлов — multipart/form-data |
| Авторизация | Authorization: Bearer <token> (Laravel Sanctum) |
| OpenAPI | /docs/openapi.json |
Быстрый старт#
Войдите, получите список чатов и отправьте сообщение:
# 1. Sign in (identifier-first wizard)
TICKET=$(curl -s -X POST https://minchatapp.com/api/auth/start \
-H 'Content-Type: application/json' -H 'Accept: application/json' \
-d '{"identifier":"anna@example.com"}' | jq -r .ticket)
TOKEN=$(curl -s -X POST https://minchatapp.com/api/auth/password \
-H 'Content-Type: application/json' -H 'Accept: application/json' \
-d "{\"ticket\":\"$TICKET\",\"password\":\"Secret123\"}" | jq -r .token)
# 2. List conversations
curl -s https://minchatapp.com/api/conversations \
-H "Authorization: Bearer $TOKEN" -H 'Accept: application/json'
# 3. Send a message
curl -s -X POST https://minchatapp.com/api/conversations/12/messages \
-H "Authorization: Bearer $TOKEN" -H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-d '{"content":"Hello from the API 👋"}'
const API = 'https://minchatapp.com/api';
async function call(path, { token, method = 'GET', body } = {}) {
const res = await fetch(API + path, {
method,
headers: {
Accept: 'application/json',
...(body ? { 'Content-Type': 'application/json' } : {}),
...(token ? { Authorization: `Bearer ${token}` } : {}),
},
body: body ? JSON.stringify(body) : undefined,
});
const data = await res.json();
if (!res.ok) throw Object.assign(new Error(data.message), { code: data.code, status: res.status });
return data;
}
const { ticket } = await call('/auth/start', { method: 'POST', body: { identifier: 'anna@example.com' } });
const { token } = await call('/auth/password', { method: 'POST', body: { ticket, password: 'Secret123' } });
const chats = await call('/conversations', { token });
await call(`/conversations/${chats[0].id}/messages`, { token, method: 'POST', body: { content: 'Hello 👋' } });
import requests
API = "https://minchatapp.com/api"
s = requests.Session()
s.headers["Accept"] = "application/json"
ticket = s.post(f"{API}/auth/start", json={"identifier": "anna@example.com"}).json()["ticket"]
token = s.post(f"{API}/auth/password", json={"ticket": ticket, "password": "Secret123"}).json()["token"]
s.headers["Authorization"] = f"Bearer {token}"
chats = s.get(f"{API}/conversations").json()
msg = s.post(f"{API}/conversations/{chats[0]['id']}/messages", json={"content": "Hello 👋"}).json()
print(msg["id"])
Аутентификация#
Все защищённые методы требуют токен Sanctum в Authorization: Bearer <token>. Токены выдают методы входа (пароль, одноразовый код, QR, Google OAuth); сами они не истекают. Каждый токен — сессия, которую пользователь видит и может завершить в Настройки → Устройства (GET /api/user/sessions). Заблокированный аккаунт получает 403 с code: "banned".
Необязательные заголовки клиента, подписывающие сессию:
| Заголовок | Значение |
|---|---|
X-Client-Platform | web, desktop, android, … |
X-Client-Version | Версия приложения, например 1.0.45 |
X-Device-Name | Название устройства |
Accept-Language | Задаёт язык аккаунта при регистрации (ru / en) |
Все способы входа — в разделе Аутентификация.
Ошибки#
Ошибки приходят в едином конверте. code — стабильный машинный идентификатор (domain.snake_case); error и message — один и тот же английский текст. Ошибки валидации (422) добавляют errors (поле → сообщения) и error_codes (поле → коды). Полный каталог — на странице Ошибки.
{
"success": false,
"code": "validation.failed",
"error": "The given data was invalid.",
"message": "The given data was invalid.",
"errors": { "send_at": ["The time is too far in the future."] },
"error_codes": { "send_at": ["validation.failed"] }
}
| Статус | Типичные коды |
|---|---|
400 | Операция неприменима (например, conversation.private_not_editable) |
401 | common.unauthenticated, auth.invalid_credentials, auth.oauth_expired |
403 | common.forbidden, banned, conversation.not_member, conversation.banned |
404 | common.not_found, conversation.channel_not_found, bot.not_found |
409 | Конфликты (например, выход владельца канала: conversation.owner_must_transfer) |
419 | common.csrf — cookie-сессия без Bearer и протухший CSRF |
422 | validation.failed, message.empty, … |
429 | common.throttled, auth.too_many_attempts |
500 / 503 | common.server_error; 503, если зависимость (например, звонки/LiveKit) не настроена |
Ограничения частоты#
Лимиты задаются на маршрут и пользователя (или IP для публичных маршрутов). У каждого метода в справочнике указан лимит, например 60/мин. При превышении — 429 с code: "common.throttled" и стандартными заголовками Retry-After, X-RateLimit-Limit, X-RateLimit-Remaining. Маршруты без явного лимита тоже защищены; не опрашивайте чаще раза в секунду.
| Область | Лимит |
|---|---|
| Отправка сообщений | 60/min |
| Редактирование/удаление, реакции, опросы | 60/min |
| Поиск (сообщения, пользователи) | 30/min |
| Статус набора, черновики, прочтение упоминаний | 120/min |
| Вход | 10–20/min; /register 5 per 10 min |
| Bot API (на маршрут) | 120/min |
| Пинг звонка | 240/min |
Пагинация#
Единой схемы нет — каждый список использует подходящий курсор:
| Метод | Схема |
|---|---|
GET /conversations/{id} | before_id / after_id / around_id + limit (≤ 100), has_more |
GET /conversations/{id}/messages/search | before_id, по 20 |
GET /messages/search | before_id → next_before_id, по 30 |
GET /conversations/{id}/media | offset/limit по вложениям → next_offset, has_more |
GET /conversations/{id}/info | after + after_role → members_has_more |
GET /conversations/{id}/bans | after (ban_id) + limit → bans_has_more |
GET /conversations | без пагинации (все чаты) |
Bot getUpdates | offset (подтверждение) + limit ≤ 100 |
Соглашения#
- id — целые числа; id вложений — строки UUID.
- Время — ISO 8601 в UTC (например,
2026-10-22T09:06:13+00:00или…000000Z). В Bot API — Unix time (date). - Булевы значения в multipart можно передавать как
1/0. - Передавайте
Accept: application/json, чтобы ошибки возвращались в JSON. - Передавайте
client_id(UUID) с сообщениями, чтобы повторы были идемпотентны. - URL вложений (
/storage/media/…) требуют тот же Bearer — передавайте его только на хост Min.
Версионирование#
Версии в URL нет. API развивается аддитивно: новые поля и методы могут появиться в любой момент — игнорируйте незнакомые поля. Ломающих изменений избегаем; legacy-методы (например, /api/login, /api/files/…) остаются для старых клиентов. Нативные клиенты получают политику обновлений через GET /api/client-updates (update: soft|force).
Публичные веб-адреса#
| URL | Страница |
|---|---|
/c/{username} | Публичная страница канала |
/c/{username}/{message} | Публичный пост |
/channels | Каталог каналов |
/join/{code} | Приглашение в группу/канал |
/u/{token}, /u/{username} | Ссылка-контакт |
/e/{slug} | Набор эмодзи |
/invite/{code} | Приглашение в сервис |
/web | Веб-приложение |