REST API
Аутентификация
Способы входа: мастер identifier-first, одноразовые коды, QR, Google OAuth, сессии и устройства.
В Min нет облачного пароля и 2FA. Рекомендуемый путь — мастер identifier-first: start → (password | request-code → verify-code) → токен. Новые аккаунты завершают шагом register. Шаги связаны 48-символьным ticket.
POST /api/auth/start {identifier}
├─ next=password ─▶ POST /api/auth/password {ticket,password} ─▶ {token,user}
│ └▶ POST /api/auth/request-code {ticket} ─▶ POST /api/auth/verify-code {ticket,code} ─▶ {token,user}
├─ next=code ─────▶ POST /api/auth/verify-code ─▶ {next:"name"} ─▶ POST /api/auth/register {ticket,name,password}
└─ next=invite ───▶ POST /api/auth/register {ticket,name,password,invite_code}
Вход по QR#
- Неавторизованное устройство вызывает
POST /api/auth/qrи показываетqr(minchat-login:<token>) как QR-код. - Подписывается на публичный канал из
channel(qr-login.<hash>) и/или опрашиваетPOST /api/auth/qr/pollраз в 1–2 с. - Авторизованный телефон сканирует код, вызывает
inspect, затемconfirmилиdecline. pollодин раз возвращаетstatus: confirmedсtokenиuser.
Google OAuth (веб)#
Откройте /auth/google в браузере. После callback пользователь попадает на /web с одноразовой cookie oauth_exchange; веб-клиент сразу вызывает POST /auth/oauth-exchange и получает Bearer-токен.
Вход, регистрация, пароль#
Начать вход (identifier-first)
Шаг 1 мастера входа. Нормализует идентификатор (email → нижний регистр, телефон → E.164), ищет аккаунт и решает, какой шаг следующий. Возвращает ticket (48 символов), который связывает следующие шаги. next: password — аккаунт существует, code — новый аккаунт вне РФ (код отправлен), invite — новый аккаунт в РФ (регистрация только по приглашению). Облачного пароля / 2FA нет.
Параметры
| Имя | Тип | Описание |
|---|---|---|
identifier
обязательный тело
|
string |
Email или номер телефона. max 255 chars
|
Запрос
curl -X POST 'https://minchatapp.com/api/auth/start' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-d '{"identifier": "anna@example.com"}'
Ответ
{
"success": true,
"next": "password",
"ticket": "NOtN0Li5lPE01BIr6Gx6iBAOspXxUp9f9nBmnxWPOlsLcosG",
"region": "other",
"can_request_code": true
}
Войти по паролю
Шаг 2 для существующего аккаунта. Возвращает токен Sanctum и пользователя.
Параметры
| Имя | Тип | Описание |
|---|---|---|
ticket
обязательный тело
|
string |
ticket из /auth/start.exactly 48 chars
|
password
обязательный тело
|
string |
Пароль аккаунта. |
Запрос
curl -X POST 'https://minchatapp.com/api/auth/password' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-d '{"ticket": "<ticket>", "password": "Secret123"}'
Ответ
{
"success": true,
"user": {
"id": 3,
"name": "Vera Kotova",
"email": "vera@example.com",
"created_at": "2026-10-20T11:12:46.000000Z",
"updated_at": "2026-10-22T09:12:49.000000Z",
"avatar": null,
"last_seen_at": "2026-10-22T09:12:49.000000Z",
"push_notifications_enabled": true,
"invited_by_id": null,
"invite_id": null,
"locale": "ru",
"default_history_ttl": 0,
"phone": null,
"about": null,
"birthday": null,
"username": null,
"is_bot": false,
"phone_verified_at": null,
"avatar_url": null
},
"token": "17|Q2pXexampleSanctumToken0000000000000000000"
}
401 wrong
{
"success": false,
"code": "auth.ticket_invalid",
"error": "Sign-in session expired. Start again.",
"message": "Sign-in session expired. Start again."
}
Запросить одноразовый код
Отправляет одноразовый код входа вместо пароля. Доставка: активный клиент MinChat этого аккаунта (в приложении, событие LoginCodeRequested), SMS для телефонов вне РФ, либо email. В РФ — только в приложении. Пауза: SMS 60 с, email/приложение 30 с.
Параметры
| Имя | Тип | Описание |
|---|---|---|
ticket
обязательный тело
|
string |
ticket из /auth/start.exactly 48 chars
|
Запрос
curl -X POST 'https://minchatapp.com/api/auth/request-code' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-d '{"ticket": "<ticket>"}'
Ответ
Отвечает HTTP 200.
Отправить код повторно
То же, что request-code, с учётом паузы.
Параметры
| Имя | Тип | Описание |
|---|---|---|
ticket
обязательный тело
|
string |
ticket из /auth/start.exactly 48 chars
|
Запрос
curl -X POST 'https://minchatapp.com/api/auth/resend-code' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-d '{"ticket": "<ticket>"}'
Ответ
Отвечает HTTP 200.
Проверить одноразовый код
Существующий аккаунт → token + user. Новый аккаунт (вне РФ) → {"next":"name"}, дальше /auth/register.
Параметры
| Имя | Тип | Описание |
|---|---|---|
ticket
обязательный тело
|
string |
ticket из /auth/start.exactly 48 chars
|
code
обязательный тело
|
string |
6-значный код. max 12 chars
|
Запрос
curl -X POST 'https://minchatapp.com/api/auth/verify-code' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-d '{"ticket": "<ticket>", "code": "123456"}'
Ответ
Отвечает HTTP 200.
Завершить регистрацию
invite_code обязателен только для региона ru. Возвращает token + user.
Параметры
| Имя | Тип | Описание |
|---|---|---|
ticket
обязательный тело
|
string |
ticket из /auth/start.exactly 48 chars
|
name
обязательный тело
|
string |
Отображаемое имя. max 255 chars
|
password
обязательный тело
|
string |
Новый пароль. requires
password_confirmationmin 8, letters + digits |
invite_code
необязательный тело
|
string |
Код приглашения (только РФ). max 32 chars
|
Запрос
curl -X POST 'https://minchatapp.com/api/auth/register' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-d '{"ticket": "<ticket>", "name": "Anna Smith", "password": "Secret123", "password_confirmation": "Secret123"}'
Ответ
Отвечает HTTP 200.
Вход по email и паролю (legacy)
Одношаговый вход для старых клиентов; новым клиентам — /auth/*. После 5 неудачных попыток за 15 минут с одного IP — 429.
Параметры
| Имя | Тип | Описание |
|---|---|---|
email
обязательный тело
|
string |
Email аккаунта. email
|
password
обязательный тело
|
string |
Пароль. |
Запрос
curl -X POST 'https://minchatapp.com/api/login' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-d '{"email": "anna@example.com", "password": "Secret123"}'
Ответ
{
"success": true,
"user": {
"id": 3,
"name": "Vera Kotova",
"email": "vera@example.com",
"created_at": "2026-10-20T11:12:46.000000Z",
"updated_at": "2026-10-22T09:12:48.000000Z",
"avatar": null,
"last_seen_at": "2026-10-22T09:12:48.000000Z",
"push_notifications_enabled": true,
"invited_by_id": null,
"invite_id": null,
"locale": "ru",
"default_history_ttl": 0,
"phone": null,
"about": null,
"birthday": null,
"username": null,
"is_bot": false,
"phone_verified_at": null,
"avatar_url": null
},
"token": "17|Q2pXexampleSanctumToken0000000000000000000"
}
401 401
{
"success": false,
"code": "auth.invalid_credentials",
"error": "Invalid email or password",
"message": "Invalid email or password"
}
Регистрация по email (legacy)
Legacy-регистрация. Ответ как у /login.
Параметры
| Имя | Тип | Описание |
|---|---|---|
name
обязательный тело
|
string |
Имя. max 255 chars
|
email
обязательный тело
|
string |
Email. emailunique
|
password
обязательный тело
|
string |
Пароль. requires
password_confirmationmin 8, letters + digits |
invite_code
необязательный тело
|
string |
Код приглашения (если требуется). |
Запрос
curl -X POST 'https://minchatapp.com/api/register' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-d '{"name": "Anna Smith", "email": "anna@example.com", "password": "Secret123", "password_confirmation": "Secret123", "invite_code": "ABCDEF"}'
Ответ
Отвечает HTTP 200.
Выйти
Отзывает текущий токен, либо все токены аккаунта с ?all=1 (или {"all":true}). Отозванные сессии получают SessionsRevoked.
Параметры
| Имя | Тип | Описание |
|---|---|---|
all
необязательный тело
|
boolean |
Отозвать все токены аккаунта. |
Запрос
curl -X POST 'https://minchatapp.com/api/logout' \
-H "Authorization: Bearer $TOKEN" \
-H 'Accept: application/json'
Ответ
{
"success": true,
"code": "auth.logged_out",
"message": "Logged out."
}
Отправить ссылку сброса пароля
Всегда отвечает нейтральным текстом. client: desktop → minchat://reset-password/…, android/app → minchatapp://reset-password/…, иначе web-ссылка /password/reset/{token}.
Параметры
| Имя | Тип | Описание |
|---|---|---|
email
обязательный тело
|
string |
Email. emailmax 255 chars
|
client
необязательный тело
|
string |
Где открыть ссылку: desktop, android, app или web (по умолчанию). |
Запрос
curl -X POST 'https://minchatapp.com/api/forgot-password' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-d '{"email": "anna@example.com", "client": "android"}'
Ответ
{
"success": true,
"code": "password.reset_sent",
"message": "If an account exists, we sent a password reset email."
}
Сбросить пароль
По токену из письма.
Параметры
| Имя | Тип | Описание |
|---|---|---|
token
обязательный тело
|
string |
Токен из письма. |
email
обязательный тело
|
string |
Email. email
|
password
обязательный тело
|
string |
Пароль. requires
password_confirmationmin 8, letters + digits |
Запрос
curl -X POST 'https://minchatapp.com/api/reset-password' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-d '{"token": "<from-email>", "email": "anna@example.com", "password": "NewSecret123", "password_confirmation": "NewSecret123"}'
Ответ
Отвечает HTTP 200.
Сменить пароль
Нужен текущий пароль.
Параметры
| Имя | Тип | Описание |
|---|---|---|
current_password
обязательный тело
|
string |
Текущий пароль. |
password
обязательный тело
|
string |
Пароль. requires
password_confirmationmust differ from current_passwordmin 8, letters + digits |
Запрос
curl -X POST 'https://minchatapp.com/api/change-password' \
-H "Authorization: Bearer $TOKEN" \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-d '{"current_password": "Secret123", "password": "NewSecret123", "password_confirmation": "NewSecret123"}'
Ответ
{
"success": false,
"code": "password.wrong_current",
"error": "Current password is incorrect.",
"message": "Current password is incorrect."
}
Создать запрос входа по QR
Вызывает неавторизованный десктоп/веб. Покажите qr как QR-код; живёт expires_in секунд (90). Затем опрашивайте /auth/qr/poll с poll_token или подпишитесь на публичный канал channel и ждите QrLoginUpdated.
Параметры
Без параметров.
Запрос
curl -X POST 'https://minchatapp.com/api/auth/qr' \
-H 'Accept: application/json'
Ответ
{
"qr": "minchat-login:sBopO38GonBMQ39qB3d2lEGwXPEdkKV6QYR96PqYFQ1Bq4M8",
"poll_token": "3KFapxV62nDlATwjomaI5HqHB9HyBCVTYo7TqNX6pxdNsVjp",
"channel": "qr-login.e4a27d213ac0f5cc88a2d3df9fb46f3c53315953b9f5082e89e088fd78844e5a",
"expires_at": "2026-10-22T09:07:43+00:00",
"expires_in": 90
}
Опросить статус QR-входа
status: pending, confirmed (тогда в ответе token и user — токен выдаётся один раз), consumed, declined, expired. Неизвестный токен тоже даёт expired.
Параметры
| Имя | Тип | Описание |
|---|---|---|
poll_token
обязательный тело
|
string |
poll_token из /auth/qr.max 128 chars
|
Запрос
curl -X POST 'https://minchatapp.com/api/auth/qr/poll' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-d '{"poll_token": "<poll_token>"}'
Ответ
{
"status": "expired"
}
Посмотреть отсканированный QR
Авторизованный телефон показывает, кто просит вход (устройство, платформа, IP, город), перед подтверждением.
Параметры
| Имя | Тип | Описание |
|---|---|---|
token
обязательный тело
|
string |
Содержимое QR ( minchat-login:…) или его токен. |
Запрос
curl -X POST 'https://minchatapp.com/api/auth/qr/inspect' \
-H "Authorization: Bearer $TOKEN" \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-d '{"token": "minchat-login:<token>"}'
Ответ
Отвечает HTTP 200.
Подтвердить вход по QR
Создаёт новую сессию для запросившего устройства. Оно получает QrLoginUpdated {status:"confirmed"}.
Параметры
| Имя | Тип | Описание |
|---|---|---|
token
обязательный тело
|
string |
Содержимое QR ( minchat-login:…) или его токен. |
Запрос
curl -X POST 'https://minchatapp.com/api/auth/qr/confirm' \
-H "Authorization: Bearer $TOKEN" \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-d '{"token": "minchat-login:<token>"}'
Ответ
Отвечает HTTP 200.
Отклонить вход по QR
Запросившее устройство получает QrLoginUpdated {status:"declined"}.
Параметры
| Имя | Тип | Описание |
|---|---|---|
token
обязательный тело
|
string |
Содержимое QR ( minchat-login:…) или его токен. |
Запрос
curl -X POST 'https://minchatapp.com/api/auth/qr/decline' \
-H "Authorization: Bearer $TOKEN" \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-d '{"token": "minchat-login:<token>"}'
Ответ
Отвечает HTTP 200.
Вход через Google (web-редирект)
Редирект браузера в Google. Необязательный ?invite=CODE сохраняется в сессии для регистрации. Не под /api.
Параметры
| Имя | Тип | Описание |
|---|---|---|
invite
необязательный query
|
string |
Код приглашения для новых аккаунтов. |
Запрос
curl 'https://minchatapp.com/auth/google' \
-H 'Accept: application/json'
Ответ
Отвечает HTTP 200.
Callback Google OAuth
При успехе редиректит на /web и ставит короткоживущую httpOnly-cookie oauth_exchange (2 минуты). Ошибки — редирект на /?error=… (invite_required, account_banned, google_auth_failed, …).
Параметры
Без параметров.
Запрос
curl 'https://minchatapp.com/auth/google/callback' \
-H 'Accept: application/json'
Ответ
Отвечает HTTP 200.
Обменять OAuth-код Google на токен
Веб-клиент вызывает сразу после редиректа. Читает одноразовую cookie oauth_exchange и возвращает {success:true, token}; 204 — нечего обменивать, 401 auth.oauth_expired — истёк.
Параметры
Без параметров.
Запрос
curl -X POST 'https://minchatapp.com/auth/oauth-exchange' \
-H 'Accept: application/json'
Ответ
Отвечает HTTP 200.
Сессии и устройства#
Список сессий (устройств)
Каждый токен Sanctum — отдельная сессия. current — токен текущего запроса. platform/client/app_version/device_name берутся из заголовков X-Client-Platform, X-Client-Version, X-Device-Name и User-Agent; location — по IP.
Параметры
Без параметров.
Запрос
curl 'https://minchatapp.com/api/user/sessions' \
-H "Authorization: Bearer $TOKEN" \
-H 'Accept: application/json'
Ответ
{
"sessions": [
{
"id": 1,
"current": true,
"label": "Laptop",
"device_name": "Chrome, macOS",
"client": "web",
"app_version": null,
"ip": "203.0.113.10",
"location": "Moscow, Russia",
"platform": "Web",
"created_at": "2026-10-20T11:12:45+00:00",
"last_used_at": "2026-10-22T09:06:13+00:00"
},
{
"id": 19,
"current": false,
"label": "Chrome",
"device_name": "Mac",
"client": "desktop",
"app_version": "1.0.44",
"ip": "203.0.113.10",
"location": null,
"platform": "macOS",
"created_at": "2026-10-21T07:17:33+00:00",
"last_used_at": "2026-10-21T07:18:34+00:00"
}
]
}
Завершить сессию
Отзывает один токен; устройство получает SessionsRevoked.
Параметры
| Имя | Тип | Описание |
|---|---|---|
id
обязательный путь
|
integer |
id сессии (токена). |
Запрос
curl -X DELETE 'https://minchatapp.com/api/user/sessions/19' \
-H "Authorization: Bearer $TOKEN" \
-H 'Accept: application/json'
Ответ
{
"success": true
}
Завершить все другие сессии
Отзывает все токены, кроме текущего.
Параметры
Без параметров.
Запрос
curl -X DELETE 'https://minchatapp.com/api/user/sessions' \
-H "Authorization: Bearer $TOKEN" \
-H 'Accept: application/json'
Ответ
{
"success": true,
"terminated": 11
}