Справочник: пользователи и профиль
/users — ручки сайта ($API/site/$SITE/users), /me — ручки сети ($API/me), сайт им не нужен. $API — https://onpress.pro/api/v2, $OP_TOKEN — ваш токен (op_XXXX). Подробно — пользователи и профиль, про сам токен — доступ.
Пользователи сайта
| Пункт | Ручка | Тело |
|---|---|---|
| Список | GET /users | — |
| Добавить | POST /users | {"email": "anna@example.com", "name": "Anna"} |
| Снять с сайта | DELETE /users/{id} | — |
Список
curl -s -H "Authorization: Bearer $OP_TOKEN" "$API/site/$SITE/users"
{
"success": true,
"site_id": "x9HTLHECq",
"total": 1,
"users": [
{ "id": null, "invite_id": 12, "email": "docs-proba-invite@example.com", "name": "Проба приглашения", "avatar": "https://secure.gravatar.com/avatar/…?s=96&d=mm&r=g", "is_super_admin": false, "added_at": "2026-09-25T20:25:37.000Z", "last_login_at": null, "status": "invited", "invited_by": 1 }
]
}
Поля строки: id, invite_id, email, name, avatar (как в профиле: Google, Telegram или Gravatar), is_super_admin, added_at, last_login_at, status (active или invited), invited_by.
Добавить
| Поле | Смысл |
|---|---|
email | обязательно, до 100 символов |
name | имя для новой учётки и приглашения |
curl -s -X POST "$API/site/$SITE/users" \
-H "Authorization: Bearer $OP_TOKEN" -H 'Content-Type: application/json' \
-d '{"email": "docs-proba-invite@example.com", "name": "Проба приглашения"}'
{ "success": true, "site_id": "x9HTLHECq", "user": { "id": null, "invite_id": 12, "email": "docs-proba-invite@example.com", "status": "invited", "…": "…" }, "created": true, "already_member": false, "invited": true }
201. Почта уже в сети — created: false, invited: false, человек сразу администратор. Отказы: 400 invalid_email, 400 invalid_name, 409 already_member, 409 already_invited.
Снять с сайта
{id} — id пользователя или invite-<id> приглашения.
curl -s -X DELETE "$API/site/$SITE/users/invite-12" -H "Authorization: Bearer $OP_TOKEN"
{ "success": true, "site_id": "x9HTLHECq", "removed": { "id": null, "invite_id": 12, "email": "docs-proba-invite@example.com", "name": "Проба приглашения" } }
Отказы: 400 invalid_user_id, 404 not_member, 404 invite_not_found, 409 cannot_remove_self, 409 last_admin, 403 insufficient_role (снять суперадмина может только суперадмин).
Свой профиль
| Пункт | Ручка | Тело |
|---|---|---|
| Профиль | GET /me | — |
| Изменить | PATCH /me | {"name": "Anna", "dashboard_lang": "ru"} |
Профиль
curl -s -H "Authorization: Bearer $OP_TOKEN" "$API/me"
{
"success": true,
"user": { "id": 42, "name": "Anna", "email": "anna@example.com", "avatar": "…", "is_super_admin": false, "registered": "2025-03-01T10:00:00.000Z", "last_login_at": "2026-09-25T09:02:10.000Z", "dashboard_lang": "ru" },
"sites_count": 3,
"api_token": { "prefix": "op_xxxxxxxx", "created_at": "2026-09-16T13:04:25.000Z", "last_used_at": "2026-09-25T20:11:36.000Z" }
}
api_token — префикс, дата выпуска и последнего обращения; null — токена нет. Самого токена здесь нет — его отдаёт GET /me/api-token. impersonated_by — {id, name, email} суперадмина, если сессия открыта входом под этим пользователем, иначе null.
Аватар. user.avatar — фото аккаунта Google, если вы входили через Google; иначе фото Telegram, если входили через Telegram; иначе Gravatar по почте (серый силуэт, если картинки на Gravatar нет). Фото Google обновляется при каждом входе через Google. Тот же адрес отдают GET /auth/me, POST /auth/session и строки GET /users. Своей загрузки аватара нет. Картинки Google не открываются со сторонним Referer — выводите их с referrerpolicy="no-referrer".
Изменить
| Поле | Правило |
|---|---|
name | не пустое, до 250 символов |
email | адрес, свободный в сети |
dashboard_lang | en, ru или "" (сбросить) |
Ответ — как у GET /me. Отказы: 400 nothing_to_update, 400 invalid_name, 400 invalid_email, 400 invalid_dashboard_lang (allowed), 409 email_taken.
Вход и пароль
| Пункт | Ручка | Тело |
|---|---|---|
| Способы входа | GET /me/auth | — |
| Задать пароль | POST /me/password | {"password": "…"} |
Обе ручки читают и меняют вход того пользователя, чьей сессией или токеном сделан запрос. Под входом под пользователем это тот, под кем вошли, а не суперадмин: так можно зайти под человеком, который не может войти, и тут же выдать ему пароль. В журнал входов под пользователем при этом пишется настоящий автор действия.
Пароль хранит Firebase, а не WordPress, поэтому обе ручки требуют сервисный ключ Firebase на сервере. Ключа нет — 503 firebase_admin_key_missing; пакет firebase-admin не установлен — 503 auth_not_configured. Это отказы, а не пустой ответ: панель по ним переходит на запасной путь.
Способы входа
Чем человек на самом деле входит — по данным Firebase, а не по сессии браузера. Поэтому ответ одинаков и в обычной панели, и под входом под пользователем.
curl -s -H "Authorization: Bearer $OP_TOKEN" "$API/me/auth"
{
"success": true,
"email": "anna@example.com",
"last_login_at": "2026-10-07T10:04:19.000Z",
"firebase": "linked",
"has_password": true,
"google": { "email": "anna@example.com" }
}
| Поле | Что значит |
|---|---|
email | почта учётной записи в сети |
last_login_at | последний вход, как в списке пользователей; null — входов не было |
firebase | linked — аккаунт Firebase найден; none — его нет вовсе |
has_password | можно ли войти по почте с паролем |
google | {email} — вход через Google подключён; null — нет |
Аккаунт Firebase ищется сначала по связке, записанной при входе, а если её нет — по почте учётной записи. Не нашёлся ни так, ни так — firebase: "none", has_password: false, google: null: это честное «входа ещё нет», а не ошибка. Ответ не кэшируется.
Задать пароль
Задаёт новый пароль себе. Пароль был — он заменяется; пароля не было (вход только через Google) — он добавляется, и вход через Google при этом сохраняется. Нет и самого аккаунта Firebase — он заводится с почтой учётной записи, и firebase в предыдущей ручке становится linked.
curl -s -X POST -H "Authorization: Bearer $OP_TOKEN" -H "Content-Type: application/json" \
-d '{"password": "NEW_PASSWORD"}' "$API/me/password"
{ "success": true, "user": { "id": 19, "email": "anna@example.com", "name": "Anna" } }
Пароль — от 8 до 4096 символов. Подтверждение вторым полем не нужно, прежний пароль вводить не требуется: правом служит сама сессия или токен.
Отказы: 400 weak_password — короче 8 символов либо Firebase счёл пароль слишком простым; 400 invalid_password — длиннее 4096; 409 no_email — у учётной записи нет почты, к которой привязать вход; 409 firebase_email_taken — эту почту уже занял другой аккаунт Firebase; 404 user_not_found — учётной записи нет в сети или она заблокирована; 502 firebase_admin_error — Firebase отказал, машинный код в firebase_code; 503 firebase_admin_key_missing. Частота — 20 запросов в минуту.
Токен API
| Пункт | Ручка | Тело |
|---|---|---|
| Показать свой токен | GET /me/api-token | — |
| Выпустить заново | POST /me/api-token | — |
| Отозвать | DELETE /me/api-token | — |
Показать свой токен
Отдаёт ваш действующий токен целиком — например, чтобы подставить его в задание нейросети. Только владельцу: другого пользователя этой ручкой не адресовать.
curl -s -H "Authorization: Bearer $OP_TOKEN" "$API/me/api-token"
{ "success": true, "token": "op_XXXX" }
Ответ с Cache-Control: no-store. Токен хранится зашифрованным, поэтому показывается сколько угодно раз — но только выпущенный с 1 октября 2026 года: у более старых сохранён только хеш, и их нужно один раз выпустить заново.
Отказы: 404 token_missing — токена нет, выпустите его; 409 token_not_recoverable — токен выпущен до 1 октября 2026 года, показать его нельзя, только выпустить заново; 403 impersonated — сессия открыта входом под другим пользователем, его токен не отдаётся и суперадмину.
Выпустить заново
Выпустить токен заново. Ответ — как у GET /me плюс token — новый токен целиком; потом его можно снова получить через GET /me/api-token. Прежний токен перестаёт работать сразу, у всех скриптов и агентов, которые им пользуются.
Отозвать
Отозвать токен. Ответ — как у GET /me с api_token: null и revoked (true, если было что отзывать).