Состояние API
Здесь проверка сервиса и эндпоинты входа в консоль; агенту с токеном op_ из них нужен только GET /health, а как устроен вход для человека — на странице «Дашборд и вход».
Во всех примерах API — https://onpress.pro/api/v2, SITE — id сайта (SITE_ID), OP_TOKEN — токен op_XXXX. Полный перечень эндпоинтов — в справочнике API.
GET /health
Отвечает, жив ли сервис и доступна ли база; токен не нужен, префикса сайта нет. Например:
curl -s "$API/health"
{ "ok": true, "db": true, "realm": "prod" }
| Поле | Тип | Описание |
|---|---|---|
ok | boolean | сервис отвечает |
db | boolean | база доступна |
realm | строка | контур экземпляра API: prod у рабочего адреса https://onpress.pro/api/v2 |
| Код | Статус | Когда | Что делать |
|---|---|---|---|
| — | 503 | сервис жив, база недоступна: "db": false | повторить позже |
Эндпоинты /auth
Эндпоинты /auth обслуживают сессию консоли и работают без префикса сайта. Все они, кроме GET /auth/me, принимают только POST; на GET они отвечают 405 method_not_allowed с заголовком Allow: POST. Все, кроме входа, работают по кукам сессии, а запрос с чужого адреса отклоняется 403 cross_origin. Отказы приходят в форме {code, message, data: {status}}, попыток входа — до 30 в минуту с одного адреса. Например, проверка сессии без куки:
curl -s "$API/auth/me"
{ "code": "no_session", "message": "sign in first", "data": { "status": 401 } }
POST /auth/session
Обменивает ID-токен Firebase на сессию консоли. Вход принимается почтой с паролем и через Google; почта должна быть подтверждена, а человек — уже быть пользователем OnPress или приглашённым на сайт. Ответ — 201 и две httpOnly-куки: сессионная на 15 минут и долгая для продления на 30 дней. Например:
curl -s -X POST "$API/auth/session" \
-H "Authorization: Bearer $FIREBASE_ID_TOKEN"
| Поле | Где | Тип | По умолчанию | Описание |
|---|---|---|---|---|
| ID-токен | Authorization: Bearer | строка | — | ID-токен Firebase после входа |
id_token | тело | строка | — | то же, если заголовка нет |
{
"success": true,
"user": { "id": 42, "email": "anna@example.com", "name": "Anna", "avatar": "https://lh3.googleusercontent.com/…", "is_super_admin": false },
"session": { "id": "…", "expires_at": "…", "expires_in": 900, "realm": "prod" },
"impersonated_by": null
}
avatar — фото Google, иначе Telegram, иначе Gravatar; вход через Google обновляет фото при каждом входе.
| Код | Статус | Когда | Что делать |
|---|---|---|---|
missing_id_token | 401 | нет ID-токена | передать токен в Authorization: Bearer |
invalid_id_token | 401 | ID-токен не прошёл проверку или истёк | войти в Firebase заново |
email_required | 403 | у аккаунта Firebase нет почты | войти почтой или через Google |
email_not_verified | 403 | почта не подтверждена | открыть письмо Firebase и подтвердить |
provider_not_allowed | 403 | вход не почтой и не через Google | войти почтой с паролем или через Google |
user_not_found | 403 | почты нет среди пользователей OnPress | попросить администратора сайта добавить почту |
cross_origin | 403 | запрос не с адреса консоли | войти из консоли |
too_many_requests | 429 | больше 30 попыток входа в минуту | подождать Retry-After секунд |
auth_not_configured | 503 | вход не настроен на сервере | повторить позже |
POST /auth/telegram
Открывает сессию по данным виджета входа Telegram; аккаунт Telegram должен быть уже привязан к пользователю OnPress. Ответ и куки — как у POST /auth/session. Например:
curl -s -X POST "$API/auth/telegram" \
-H "Content-Type: application/json" \
-d '{"id": 123456789, "first_name": "Anna", "auth_date": 1793135000, "hash": "…"}'
| Поле | Тип | По умолчанию | Описание |
|---|---|---|---|
id | число | — | id пользователя Telegram |
auth_date | число | — | время входа, unix; не старше суток |
hash | строка | — | подпись виджета |
first_name, last_name, username, photo_url | строка | — | остальные поля виджета, как он их прислал |
| Код | Статус | Когда | Что делать |
|---|---|---|---|
invalid_telegram_data | 400 | нет id, auth_date или hash | передать данные виджета целиком |
invalid_telegram_hash | 401 | подпись не сходится | войти через виджет заново |
telegram_auth_expired | 401 | вход старше суток | войти через виджет заново |
user_not_found | 403 | Telegram не привязан к пользователю OnPress | войти почтой или через Google |
cross_origin | 403 | запрос не с адреса консоли | войти из консоли |
too_many_requests | 429 | больше 30 попыток входа в минуту | подождать Retry-After секунд |
POST /auth/refresh
Продлевает сессию по долгой куке и меняет её секрет. Ответ — как у POST /auth/session, со статусом 200. Например:
curl -s -X POST "$API/auth/refresh" -b cookies.txt -c cookies.txt
| Код | Статус | Когда | Что делать |
|---|---|---|---|
no_session | 401 | нет долгой куки | войти заново |
session_expired | 401 | сессия истекла или отозвана | войти заново |
user_not_found | 403 | пользователя больше нет | — |
POST /auth/logout
Закрывает сессию на этом устройстве и стирает куки. Отказа не бывает: если сессии уже нет, revoked равен 0. Например:
curl -s -X POST "$API/auth/logout" -b cookies.txt
{ "success": true, "revoked": 1 }
POST /auth/logout-all
Закрывает все сессии пользователя на всех устройствах; токен API продолжает работать. Например:
curl -s -X POST "$API/auth/logout-all" -b cookies.txt
{ "success": true, "revoked": 3 }
| Код | Статус | Когда | Что делать |
|---|---|---|---|
no_session | 401 | нет действующей сессии | войти |
GET /auth/me
Возвращает, кто вошёл, и id сессии; профиль целиком — GET /me из справочника пользователей. Например:
curl -s "$API/auth/me" -b cookies.txt
{
"success": true,
"user": { "id": 42, "email": "anna@example.com", "name": "Anna", "avatar": "https://lh3.googleusercontent.com/…", "is_super_admin": false },
"session": { "id": "…", "realm": "prod" },
"impersonated_by": null
}
| Код | Статус | Когда | Что делать |
|---|---|---|---|
no_session | 401 | нет действующей сессии | войти |
user_not_found | 403 | пользователя больше нет | — |
POST /auth/ticket
Выдаёт одноразовый билет на две минуты для запроса консоли к API на домене сайта: кука консоли на чужой домен не едет. Билет выдаётся только по сессии консоли; с токеном op_ он не нужен — API на домене сайта принимает токен напрямую. Сайт называется полем site_id, blog_id или domain в теле или строке запроса, а билет предъявляется сайту заголовком Authorization: Bearer или X-OnPress-Ticket. Например:
curl -s -X POST "$API/auth/ticket" -b cookies.txt \
-H "Content-Type: application/json" \
-d '{"site_id": "x9HTLHECq"}'
| Поле | Тип | По умолчанию | Описание |
|---|---|---|---|
site_id | строка | — | id сайта |
blog_id | число | — | номер сайта, если site_id не задан |
domain | строка | — | домен сайта, если не задано ни то ни другое |
{ "success": true, "ticket": "…", "issued_at": 1793135000, "expires_at": 1793135120, "blog_id": 233, "jti": "…", "ttl": 120 }
| Код | Статус | Когда | Что делать |
|---|---|---|---|
no_session | 401 | нет сессии консоли — например, запрос с токеном op_ | с токеном обращаться к API сайта напрямую |
blog_required | 400 | сайт не назван | передать site_id |
invalid_blog_id | 400 | blog_id — не положительное целое | передать site_id |
site_not_found | 404 | сайта с таким id или доменом нет | проверить id сайта |
insufficient_role | 403 | у вас нет доступа к этому сайту | — |
cross_origin | 403 | запрос не с адреса консоли | запросить билет из консоли |