К содержимому

REST API

Аутентификация

Способы входа: мастер identifier-first, одноразовые коды, QR, Google OAuth, сессии и устройства.

В Min нет облачного пароля и 2FA. Рекомендуемый путь — мастер identifier-first: start → (password | request-code → verify-code) → токен. Новые аккаунты завершают шагом register. Шаги связаны 48-символьным ticket.

flow
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#

  1. Неавторизованное устройство вызывает POST /api/auth/qr и показывает qr (minchat-login:<token>) как QR-код.
  2. Подписывается на публичный канал из channel (qr-login.<hash>) и/или опрашивает POST /api/auth/qr/poll раз в 1–2 с.
  3. Авторизованный телефон сканирует код, вызывает inspect, затем confirm или decline.
  4. poll один раз возвращает status: confirmed с token и user.

Google OAuth (веб)#

Откройте /auth/google в браузере. После callback пользователь попадает на /web с одноразовой cookie oauth_exchange; веб-клиент сразу вызывает POST /auth/oauth-exchange и получает Bearer-токен.

Вход, регистрация, пароль#

POST /api/auth/start #

Начать вход (identifier-first)

Без авторизации Лимит: 20/min

Шаг 1 мастера входа. Нормализует идентификатор (email → нижний регистр, телефон → E.164), ищет аккаунт и решает, какой шаг следующий. Возвращает ticket (48 символов), который связывает следующие шаги. next: password — аккаунт существует, code — новый аккаунт вне РФ (код отправлен), invite — новый аккаунт в РФ (регистрация только по приглашению). Облачного пароля / 2FA нет.

Параметры

Имя Тип Описание
identifier
обязательный тело
string
Email или номер телефона.
max 255 chars

Запрос

curl
curl -X POST 'https://minchatapp.com/api/auth/start' \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{"identifier": "anna@example.com"}'

Ответ

HTTP 200
{
  "success": true,
  "next": "password",
  "ticket": "NOtN0Li5lPE01BIr6Gx6iBAOspXxUp9f9nBmnxWPOlsLcosG",
  "region": "other",
  "can_request_code": true
}
POST /api/auth/password #

Войти по паролю

Без авторизации Лимит: 10/min

Шаг 2 для существующего аккаунта. Возвращает токен Sanctum и пользователя.

Параметры

Имя Тип Описание
ticket
обязательный тело
string
ticket из /auth/start.
exactly 48 chars
password
обязательный тело
string
Пароль аккаунта.

Запрос

curl
curl -X POST 'https://minchatapp.com/api/auth/password' \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{"ticket": "<ticket>", "password": "Secret123"}'

Ответ

HTTP 200
{
  "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
HTTP 401 · wrong
{
  "success": false,
  "code": "auth.ticket_invalid",
  "error": "Sign-in session expired. Start again.",
  "message": "Sign-in session expired. Start again."
}
POST /api/auth/request-code #

Запросить одноразовый код

Без авторизации Лимит: 10/min

Отправляет одноразовый код входа вместо пароля. Доставка: активный клиент MinChat этого аккаунта (в приложении, событие LoginCodeRequested), SMS для телефонов вне РФ, либо email. В РФ — только в приложении. Пауза: SMS 60 с, email/приложение 30 с.

Параметры

Имя Тип Описание
ticket
обязательный тело
string
ticket из /auth/start.
exactly 48 chars

Запрос

curl
curl -X POST 'https://minchatapp.com/api/auth/request-code' \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{"ticket": "<ticket>"}'

Ответ

Отвечает HTTP 200.

POST /api/auth/resend-code #

Отправить код повторно

Без авторизации Лимит: 10/min

То же, что request-code, с учётом паузы.

Параметры

Имя Тип Описание
ticket
обязательный тело
string
ticket из /auth/start.
exactly 48 chars

Запрос

curl
curl -X POST 'https://minchatapp.com/api/auth/resend-code' \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{"ticket": "<ticket>"}'

Ответ

Отвечает HTTP 200.

POST /api/auth/verify-code #

Проверить одноразовый код

Без авторизации Лимит: 20/min

Существующий аккаунт → token + user. Новый аккаунт (вне РФ) → {"next":"name"}, дальше /auth/register.

Параметры

Имя Тип Описание
ticket
обязательный тело
string
ticket из /auth/start.
exactly 48 chars
code
обязательный тело
string
6-значный код.
max 12 chars

Запрос

curl
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.

POST /api/auth/register #

Завершить регистрацию

Без авторизации Лимит: 5/10 min

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
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.

POST /api/login #

Вход по email и паролю (legacy)

Без авторизации Лимит: 10/min

Одношаговый вход для старых клиентов; новым клиентам — /auth/*. После 5 неудачных попыток за 15 минут с одного IP — 429.

Параметры

Имя Тип Описание
email
обязательный тело
string
Email аккаунта.
email
password
обязательный тело
string
Пароль.

Запрос

curl
curl -X POST 'https://minchatapp.com/api/login' \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{"email": "anna@example.com", "password": "Secret123"}'

Ответ

HTTP 200
{
  "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
HTTP 401 · 401
{
  "success": false,
  "code": "auth.invalid_credentials",
  "error": "Invalid email or password",
  "message": "Invalid email or password"
}
POST /api/register #

Регистрация по email (legacy)

Без авторизации Лимит: 5/10 min

Legacy-регистрация. Ответ как у /login.

Параметры

Имя Тип Описание
name
обязательный тело
string
Имя.
max 255 chars
email
обязательный тело
string
Email.
emailunique
password
обязательный тело
string
Пароль.
requires password_confirmationmin 8, letters + digits
invite_code
необязательный тело
string
Код приглашения (если требуется).

Запрос

curl
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.

POST /api/logout #

Выйти

Bearer-токен

Отзывает текущий токен, либо все токены аккаунта с ?all=1 (или {"all":true}). Отозванные сессии получают SessionsRevoked.

Параметры

Имя Тип Описание
all
необязательный тело
boolean
Отозвать все токены аккаунта.

Запрос

curl
curl -X POST 'https://minchatapp.com/api/logout' \
  -H "Authorization: Bearer $TOKEN" \
  -H 'Accept: application/json'

Ответ

HTTP 200
{
  "success": true,
  "code": "auth.logged_out",
  "message": "Logged out."
}
POST /api/forgot-password #

Отправить ссылку сброса пароля

Без авторизации Лимит: 5/10 min

Всегда отвечает нейтральным текстом. 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
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"}'

Ответ

HTTP 200
{
  "success": true,
  "code": "password.reset_sent",
  "message": "If an account exists, we sent a password reset email."
}
POST /api/reset-password #

Сбросить пароль

Без авторизации Лимит: 10/10 min

По токену из письма.

Параметры

Имя Тип Описание
token
обязательный тело
string
Токен из письма.
email
обязательный тело
string
Email.
email
password
обязательный тело
string
Пароль.
requires password_confirmationmin 8, letters + digits

Запрос

curl
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.

POST /api/change-password #

Сменить пароль

Bearer-токен Лимит: 10/10 min

Нужен текущий пароль.

Параметры

Имя Тип Описание
current_password
обязательный тело
string
Текущий пароль.
password
обязательный тело
string
Пароль.
requires password_confirmationmust differ from current_passwordmin 8, letters + digits

Запрос

curl
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"}'

Ответ

HTTP 422 · wrong
{
  "success": false,
  "code": "password.wrong_current",
  "error": "Current password is incorrect.",
  "message": "Current password is incorrect."
}
POST /api/auth/qr #

Создать запрос входа по QR

Без авторизации Лимит: 20/min

Вызывает неавторизованный десктоп/веб. Покажите qr как QR-код; живёт expires_in секунд (90). Затем опрашивайте /auth/qr/poll с poll_token или подпишитесь на публичный канал channel и ждите QrLoginUpdated.

Параметры

Без параметров.

Запрос

curl
curl -X POST 'https://minchatapp.com/api/auth/qr' \
  -H 'Accept: application/json'

Ответ

HTTP 200
{
  "qr": "minchat-login:sBopO38GonBMQ39qB3d2lEGwXPEdkKV6QYR96PqYFQ1Bq4M8",
  "poll_token": "3KFapxV62nDlATwjomaI5HqHB9HyBCVTYo7TqNX6pxdNsVjp",
  "channel": "qr-login.e4a27d213ac0f5cc88a2d3df9fb46f3c53315953b9f5082e89e088fd78844e5a",
  "expires_at": "2026-10-22T09:07:43+00:00",
  "expires_in": 90
}
POST /api/auth/qr/poll #

Опросить статус QR-входа

Без авторизации Лимит: 90/min

status: pending, confirmed (тогда в ответе token и user — токен выдаётся один раз), consumed, declined, expired. Неизвестный токен тоже даёт expired.

Параметры

Имя Тип Описание
poll_token
обязательный тело
string
poll_token из /auth/qr.
max 128 chars

Запрос

curl
curl -X POST 'https://minchatapp.com/api/auth/qr/poll' \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{"poll_token": "<poll_token>"}'

Ответ

HTTP 200
{
  "status": "expired"
}
POST /api/auth/qr/inspect #

Посмотреть отсканированный QR

Bearer-токен Лимит: 20/min

Авторизованный телефон показывает, кто просит вход (устройство, платформа, IP, город), перед подтверждением.

Параметры

Имя Тип Описание
token
обязательный тело
string
Содержимое QR (minchat-login:…) или его токен.

Запрос

curl
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.

POST /api/auth/qr/confirm #

Подтвердить вход по QR

Bearer-токен Лимит: 10/min

Создаёт новую сессию для запросившего устройства. Оно получает QrLoginUpdated {status:"confirmed"}.

Параметры

Имя Тип Описание
token
обязательный тело
string
Содержимое QR (minchat-login:…) или его токен.

Запрос

curl
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.

POST /api/auth/qr/decline #

Отклонить вход по QR

Bearer-токен Лимит: 20/min

Запросившее устройство получает QrLoginUpdated {status:"declined"}.

Параметры

Имя Тип Описание
token
обязательный тело
string
Содержимое QR (minchat-login:…) или его токен.

Запрос

curl
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.

GET /auth/google #

Вход через Google (web-редирект)

Без авторизации Лимит: 20/min

Редирект браузера в Google. Необязательный ?invite=CODE сохраняется в сессии для регистрации. Не под /api.

Параметры

Имя Тип Описание
invite
необязательный query
string
Код приглашения для новых аккаунтов.

Запрос

curl
curl 'https://minchatapp.com/auth/google' \
  -H 'Accept: application/json'

Ответ

Отвечает HTTP 200.

GET /auth/google/callback #

Callback Google OAuth

Без авторизации Лимит: 20/min

При успехе редиректит на /web и ставит короткоживущую httpOnly-cookie oauth_exchange (2 минуты). Ошибки — редирект на /?error=… (invite_required, account_banned, google_auth_failed, …).

Параметры

Без параметров.

Запрос

curl
curl 'https://minchatapp.com/auth/google/callback' \
  -H 'Accept: application/json'

Ответ

Отвечает HTTP 200.

POST /auth/oauth-exchange #

Обменять OAuth-код Google на токен

Без авторизации Лимит: 10/min

Веб-клиент вызывает сразу после редиректа. Читает одноразовую cookie oauth_exchange и возвращает {success:true, token}; 204 — нечего обменивать, 401 auth.oauth_expired — истёк.

Параметры

Без параметров.

Запрос

curl
curl -X POST 'https://minchatapp.com/auth/oauth-exchange' \
  -H 'Accept: application/json'

Ответ

Отвечает HTTP 200.

Сессии и устройства#

GET /api/user/sessions #

Список сессий (устройств)

Bearer-токен

Каждый токен Sanctum — отдельная сессия. current — токен текущего запроса. platform/client/app_version/device_name берутся из заголовков X-Client-Platform, X-Client-Version, X-Device-Name и User-Agent; location — по IP.

Параметры

Без параметров.

Запрос

curl
curl 'https://minchatapp.com/api/user/sessions' \
  -H "Authorization: Bearer $TOKEN" \
  -H 'Accept: application/json'

Ответ

HTTP 200
{
  "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"
    }
  ]
}
DELETE /api/user/sessions/{id} #

Завершить сессию

Bearer-токен

Отзывает один токен; устройство получает SessionsRevoked.

Параметры

Имя Тип Описание
id
обязательный путь
integer
id сессии (токена).

Запрос

curl
curl -X DELETE 'https://minchatapp.com/api/user/sessions/19' \
  -H "Authorization: Bearer $TOKEN" \
  -H 'Accept: application/json'

Ответ

HTTP 200
{
  "success": true
}
DELETE /api/user/sessions #

Завершить все другие сессии

Bearer-токен

Отзывает все токены, кроме текущего.

Параметры

Без параметров.

Запрос

curl
curl -X DELETE 'https://minchatapp.com/api/user/sessions' \
  -H "Authorization: Bearer $TOKEN" \
  -H 'Accept: application/json'

Ответ

HTTP 200
{
  "success": true,
  "terminated": 11
}