API Lorachi

JSON-контракт сайта и приложения: публичный каталог, чтение, библиотека, сообщество, игры и экономика. Одна и та же документация доступна как HTML-страница и как markdown для ИИ-агентов.

Markdown для ИИ OpenAPI 3.1 llms.txt Обновлено 2026-10-20

Lorachi — юри-портал переводов: новеллы, манга, аниме, игры и сообщество. API отдаёт JSON и не требует парсинга HTML. Для нового клиента выбирайте /api/v1: это версионированный контракт с Bearer-токенами. /api/* — API самого сайта: он использует cookie-сессию и CSRF-токен для мутаций. Машинночитаемый контракт /api/v1 — OpenAPI 3.1: /api-docs/openapi.json.

Сайт использует cookie-сессию и CSRF для мутаций. Приложение — Bearer-токены через /api/v1. Публичные GET-ручки доступны без входа.

Авторизация и аккаунт

Вход на сайте живёт на cookie-сессии. Любой POST/PUT/PATCH/DELETE под /api/* требует CSRF-токен: cookie XSRF-TOKEN нужно продублировать заголовком x-xsrf-token. Нативному клиенту проще использовать /api/v1/auth/* и Bearer.

Метод Путь Доступ Что делает
GET /health без входа Живость приложения и состояние Mongo, R2 и hCaptcha.
POST /api/auth/register без входа + CSRF Регистрация в web-сессии. Тело: username, email, password, captchaToken?.
POST /api/auth/login без входа + CSRF Вход в web-сессии. Тело: login (username или email), password.
POST /api/auth/logout cookie + CSRF Выход из текущей cookie-сессии.
POST /api/auth/logout-all cookie + CSRF Выход из всех сессий пользователя.
GET /api/auth/me cookie-сессия Текущий пользователь, подписка и счётчик уведомлений.
GET /api/auth/sessions cookie-сессия Активные web-сеансы и сеансы приложения.
DELETE /api/auth/sessions/:id cookie + CSRF Завершить сеанс web:<id> или mobile:<id>.
POST /api/auth/change-password cookie + CSRF Сменить пароль и отозвать остальные сессии.
POST /api/auth/username cookie + CSRF Сменить username.
POST /api/auth/display-name cookie + CSRF Сменить отображаемое имя.
POST /api/auth/username-style cookie + CSRF Настроить стиль ника.
POST /api/auth/privacy cookie + CSRF Приватность профиля и сообщений.
POST /api/auth/bio cookie + CSRF Обновить описание профиля.
POST /api/auth/profile-customization cookie + CSRF Статус, обращение и виджеты профиля.
POST /api/auth/avatar cookie + CSRF Загрузить аватар (multipart).
DELETE /api/auth/avatar cookie + CSRF Удалить аватар.
POST /api/auth/banner cookie + CSRF Загрузить баннер профиля (multipart).
DELETE /api/auth/banner cookie + CSRF Удалить баннер.
POST /api/auth/banner-nsfw cookie + CSRF Признак 18+ у баннера.
POST /api/auth/banner-gradient cookie + CSRF Градиент баннера.
DELETE /api/auth/delete cookie + CSRF Удалить аккаунт.
GET /api/auth/links cookie-сессия Привязанные соцсети: id, label, linked, username, configured.
GET /api/auth/:provider/redirect без входа Вход через соцсеть: discord, google, twitch (OAuth 2.0) или telegram (OIDC + PKCE). Ведёт на страницу провайдера. Параметр redirect — свой путь, куда вернуть после входа.
GET /api/auth/:provider/callback без входа Callback провайдера: логин/регистрация или привязка. Браузер возвращается на сайт, Accept: application/json получает JSON. State одноразовый и лежит в сессии; у Telegram дополнительно проверяются PKCE, подпись id_token и nonce.
POST /api/auth/:provider/unlink cookie + CSRF Отвязать OAuth-провайдера.
POST /api/auth/telegram/generate-link-code cookie + CSRF Код привязки Telegram через бота (6 цифр, 10 минут). Ответ: code, expiresAt, botUrl, deepLink. Это совместимость со старым флоу; основной вход — OIDC.
GET /api/auth/telegram/check-link-status cookie-сессия Статус привязки Telegram.

Мобильный API v1

Стабильный контракт для нативного клиента. База: /api/v1. Авторизация — Authorization: Bearer <accessToken>; cookie и CSRF не используются. Access живёт 30 минут, refresh — 90 дней и ротируется при каждом обмене.

Метод Путь Доступ Что делает
POST /api/v1/auth/register без входа Регистрация, сразу возвращает пару токенов. Тело: username, email, password, captchaToken?, deviceId?.
POST /api/v1/auth/login без входа Вход по username/email и паролю. Тело: login, password, deviceId?.
POST /api/v1/auth/refresh без входа Обмен refresh-токена на новую пару. Тело: refreshToken, deviceId?.
POST /api/v1/auth/logout Bearer Выход только с этого устройства.
POST /api/v1/auth/logout-all Bearer Выход со всех устройств.
GET /api/v1/auth/me Bearer Пользователь, подписка и unread.
POST /api/v1/auth/link/start без входа Начать вход по ссылке через сайт (Lite-OAuth).
POST /api/v1/auth/link/poll без входа Опрос статуса link-входа; токены выдаются один раз.
GET /api/v1/auth/oauth/:provider/start без входа Native OAuth/PKCE: 302 в Custom Tabs к Google или Discord. query: redirect_uri, code_challenge, code_challenge_method=S256, state, deviceId?.
GET /api/v1/auth/oauth/:provider/callback без входа Callback провайдера: одноразовый код в lorachi://oauth, без токенов в URL.
POST /api/v1/auth/oauth/:provider/token без входа Обмен одноразового кода и PKCE verifier на Bearer-пару. Тело: code, codeVerifier, deviceId?. Повторный обмен — 410.
GET /api/v1/me Bearer Алиас пользователя, подписки и unread.
GET /api/v1/home гость или вход Главная: featured, updates, continueReading. С Bearer персонализируется.
GET /api/v1/catalog гость или вход Каталог новелл, манги и аниме. Фильтры: type, page, limit, genre, status, sort, order, search, featured.
GET /api/v1/search гость или вход Поиск по тайтлам, авторам и пользователям. q — 2–100 символов.
GET /api/v1/novels/:id гость или вход Карточка тайтла по ObjectId, alt или slug.
GET /api/v1/novels/:id/chapters гость или вход Список глав; limit до 100.
GET /api/v1/novels/:id/content гость или вход Том целиком для офлайна: markdown-текст или страницы манги. query: volume (по умолчанию 1). Платные главы без доступа — locked: true; том больше 4 МиБ — 413 E_VOLUME_TOO_LARGE.
GET /api/v1/chapters/:id гость или вход Текстовая глава с prev/next. Платная глава без доступа: 403 E_PAID_CHAPTER.
GET /api/v1/manga/:novelId/chapters/:chapterId/pages гость или вход Страницы манги в правильном порядке.
GET /api/v1/users/:username гость или вход Публичный профиль без email.
PATCH /api/v1/me/profile Bearer Частичная правка своего профиля. Тело: displayName, bio, status, pronouns, messagePrivacy, isPrivate — все необязательные.
POST /api/v1/users/:username/follow Bearer Подписаться (идемпотентно).
DELETE /api/v1/users/:username/follow Bearer Отписаться (идемпотентно).
GET /api/v1/users/:username/followers гость или вход Подписчики, до 200.
GET /api/v1/users/:username/following гость или вход Подписки, до 200.
GET /api/v1/users/:username/friends гость или вход Взаимные подписки, до 200.
GET /api/v1/users/search гость или вход Поиск людей по username и нику. query: q (от 2 символов), page, limit до 50.
GET /api/v1/users/online гость или вход Кто активен последние 5 минут.
POST /api/v1/activity/update Bearer Пульс присутствия для «онлайн» и карточки профиля.
GET /api/v1/comments гость или вход Комментарии с деревом ответов и liked зрителя. query: targetType, targetId, sort, page, limit.
POST /api/v1/comments Bearer Оставить комментарий или ответ (только аккаунт). Тело: targetType, targetId, content, parentId?, isAnonymous?.
POST /api/v1/comments/:id/like Bearer Лайк/анлайк комментария.
DELETE /api/v1/comments/:id Bearer Удалить свой комментарий.
GET /api/v1/anime гость или вход Каталог аниме с фильтрами и пагинацией. query: page, limit, genre, type, status, sort, order, search.
GET /api/v1/anime/:idOrSlug гость или вход Тайтл, серии по сезонам и состояние библиотеки.
GET /api/v1/anime/episodes/:id/streams без входа Источники для плеера: треки, качества, встраиваемые плееры. private, no-store; скрытая серия — 404.
GET /api/v1/anime/episodes/:id/subtitles/:player/:subtitle без входа WebVTT-субтитры через наш прокси.
POST /api/v1/devices Bearer Зарегистрировать FCM-токен устройства. Тело: token, platform?, deviceId?.
DELETE /api/v1/devices/:token Bearer Удалить FCM-токен устройства.
GET /api/v1/sessions Bearer Активные сеансы: текущее устройство и сайт.
DELETE /api/v1/sessions/:id Bearer Завершить выбранный сеанс.
GET /api/v1/library Bearer Библиотека пользователя и сводка.
POST /api/v1/library/bulk Bearer Массовая смена статуса или удаление.
PUT /api/v1/library/:kind/:id Bearer Добавить или обновить запись. kind: novel, manga, anime.
DELETE /api/v1/library/:kind/:id Bearer Убрать запись из библиотеки.
GET /api/v1/progress Bearer Последние прочитанные тайтлы.
PUT /api/v1/progress Bearer Сохранить позицию чтения.
POST /api/v1/progress/sync Bearer Слить офлайн-прогресс, last-write-wins.
GET /api/v1/notifications Bearer Уведомления и счётчики по категориям.
GET /api/v1/notifications/unread Bearer Только счётчик непрочитанных.
POST /api/v1/notifications/read Bearer Отметить выбранные или все уведомления.
POST /api/v1/notifications/clear-read Bearer Удалить прочитанные.
GET /api/v1/notifications/settings Bearer Настройки уведомлений по категориям. kinds: chapters, anime, social, rewards, games, system. Выключенная категория гасит и уведомления, и push.
PUT /api/v1/notifications/settings Bearer Частично изменить категории уведомлений. Тело: kinds — объект «категория → true/false». Меняются только присланные ключи; неизвестная категория — 422.
POST /api/v1/notifications/:id/toggle Bearer Переключить прочитано/непрочитано.
DELETE /api/v1/notifications/:id Bearer Удалить уведомление.

Каталог, поиск и тайтлы

Публичное чтение каталога. Ответы каталога кэшируются примерно на минуту; персональные поля появляются только с валидной сессией.

Метод Путь Доступ Что делает
GET /api/search без входа Глобальный поиск: novels, authors, users. q короче 2 символов даёт пустой ответ.
GET /api/catalog/novels без входа Каталог новелл. page, limit, genre, status, sort, order, search, featured.
GET /api/catalog/manga без входа Каталог манги. Те же фильтры, что у новелл.
GET /api/catalog/updates без входа Лента обновлений. Те же фильтры, что у каталога.
GET /api/catalog/recent-chapters без входа Последние главы и серии. limit до 50; type, period.
GET /api/novels/:id гость или вход Карточка тайтла по ObjectId, alt или slug.
GET /api/novels/:id/chapters гость или вход Список глав тайтла.
GET /api/novels/:id/feed без входа Лента обновлений тайтла.
GET /api/novels/:id/reviews без входа Рецензии тайтла.
POST /api/novels/:id/rate cookie + CSRF Поставить оценку тайтлу.
POST /api/novels/:id/reviews cookie + CSRF Создать рецензию.
PUT /api/reviews/:id cookie + CSRF Обновить свою рецензию.
DELETE /api/reviews/:id cookie + CSRF Удалить свою рецензию.
POST /api/reviews/:id/like cookie + CSRF Поставить или снять лайк рецензии.
GET /api/illustrations/:novelId без входа Иллюстрации тайтла.

Чтение, прогресс и личная библиотека

Ридер, прогресс, заметки, закладки и покупки. Все личные ручки требуют cookie-сессию; мутации — ещё и CSRF. Номер главы в JSON всегда строка: в базе он Mixed (12, 12.5, prologue).

Метод Путь Доступ Что делает
GET /api/chapters/:id гость или вход Текстовая глава с навигацией prev/next.
POST /api/chapters/:id/like cookie + CSRF Лайк главы.
DELETE /api/chapters/:id/like cookie + CSRF Снять лайк главы.
PUT /api/chapters/:id/react cookie + CSRF Поставить реакцию на главу.
DELETE /api/chapters/:id/react cookie + CSRF Снять реакцию.
GET /api/manga/:novelId/chapters/:chapterId/pages гость или вход Страницы манги по порядку.
POST /api/reader/heartbeat/start без входа + CSRF Начать сессию чтения.
POST /api/reader/heartbeat без входа + CSRF Продлить сессию чтения.
POST /api/reader/heartbeat/stop cookie + CSRF Завершить сессию чтения.
GET /api/reading/progress cookie-сессия Последние прочитанные тайтлы.
PUT /api/reading/progress cookie + CSRF Сохранить позицию: novelId, chapter, volume?, percent?.
POST /api/reading/progress/sync cookie + CSRF Слить офлайн-прогресс.
GET /api/reading/notes cookie-сессия Заметки и выделения пользователя.
POST /api/reading/notes cookie + CSRF Создать заметку или выделение.
PATCH /api/reading/notes/:id cookie + CSRF Обновить заметку.
DELETE /api/reading/notes/:id cookie + CSRF Удалить заметку.
GET /api/library cookie-сессия Библиотека: новеллы, манга и аниме.
GET /api/library/export cookie-сессия Экспорт библиотеки в CSV или JSON.
POST /api/library/bulk cookie + CSRF Массовая смена статуса или удаление.
PUT /api/library/:kind/:id cookie + CSRF Добавить или обновить запись. kind: novel, manga, anime.
DELETE /api/library/:kind/:id cookie + CSRF Убрать запись.
POST /api/bookmarks cookie + CSRF Добавить закладку на главу.
DELETE /api/bookmarks/:chapterId cookie + CSRF Удалить закладку.
GET /api/bookmarks cookie-сессия Список закладок.
POST /api/purchases/chapter cookie + CSRF Купить платную главу.
GET /api/purchases cookie-сессия История покупок.

Уведомления

Личные уведомления. Ответы приватные: Cache-Control: private, no-store. Счётчики и списки одинаковы для сайта и приложения, отличаются только способом входа.

Метод Путь Доступ Что делает
GET /api/notifications cookie-сессия Список уведомлений и счётчики по категориям.
GET /api/notifications/unread cookie-сессия Счётчик непрочитанных.
POST /api/notifications/read cookie + CSRF Отметить выбранные ids или все.
POST /api/notifications/clear-read cookie + CSRF Удалить прочитанные.
POST /api/notifications/:id/toggle cookie + CSRF Переключить прочитано/непрочитано.
DELETE /api/notifications/:id cookie + CSRF Удалить уведомление.

Пользователи, стена и комментарии

Социальный слой сайта. Комментарии и реакции доступны только с сессией, кроме чтения и гостевого создания комментария (капча/лимит).

Метод Путь Доступ Что делает
GET /api/users/online без входа Кто сейчас на сайте.
GET /api/users/search без входа Поиск пользователей.
GET /api/users/following cookie-сессия На кого подписан текущий пользователь.
GET /api/users/:username без входа Публичный профиль.
GET /api/users/:username/friends без входа Друзья пользователя.
GET /api/users/:username/followers без входа Подписчики.
GET /api/users/:username/following без входа Подписки.
POST /api/users/:username/follow cookie + CSRF Подписаться или отписаться.
POST /api/activity/update без входа + CSRF Heartbeat «онлайн» для гостя или пользователя.
GET /api/online/widget без входа HTML-виджет «Сейчас на сайте».
GET /api/comments без входа Комментарии к тайтлу или главе.
POST /api/comments без входа + CSRF Создать комментарий. Гостю нужна капча.
DELETE /api/comments/:id cookie + CSRF Удалить свой комментарий.
POST /api/comments/:id/like cookie + CSRF Поставить или снять лайк.
GET /api/chapters/:id/line-comments без входа Комментарии к строке главы.
POST /api/chapters/:id/line-comments cookie + CSRF Создать комментарий к строке.
POST /api/line-comments/:id/reply cookie + CSRF Ответить на комментарий к строке.
POST /api/line-comments/:id/like cookie + CSRF Лайк комментария к строке.
DELETE /api/line-comments/:id cookie + CSRF Удалить комментарий к строке.
GET /api/sse/comments без входа SSE-поток новых комментариев.
GET /api/art без входа Посты стены/галереи.
POST /api/art cookie + CSRF Создать пост.
GET /api/art/:id без входа Один пост.
DELETE /api/art/:id cookie + CSRF Удалить свой пост.
POST /api/art/:id/like cookie + CSRF Лайк поста.
POST /api/art/:id/repost cookie + CSRF Репост.
PUT /api/art/:id/comment-settings cookie + CSRF Настройки комментариев поста.
POST /api/upload cookie + CSRF Загрузка картинки в R2 (multipart).

Сообщения

Личные диалоги и групповые чаты. Все ручки требуют сессии; SSE-поток отдаёт события в реальном времени.

Метод Путь Доступ Что делает
GET /api/messages/dialogs cookie-сессия Список личных диалогов.
GET /api/messages/d/:userId cookie-сессия История личного диалога.
POST /api/messages/d/:userId cookie + CSRF Отправить личное сообщение.
POST /api/messages/read/:userId cookie + CSRF Отметить диалог прочитанным.
GET /api/messages/group-chats cookie-сессия Список групповых чатов.
POST /api/messages/group-chats cookie + CSRF Создать групповой чат.
GET /api/messages/group-chats/:id/messages cookie-сессия История группового чата.
POST /api/messages/group-chats/:id/messages cookie + CSRF Отправить сообщение в чат.
POST /api/messages/group-chats/:id/join cookie + CSRF Войти в чат.
POST /api/messages/group-chats/:id/leave cookie + CSRF Выйти из чата.
POST /api/messages/group-messages/:id/vote cookie + CSRF Проголосовать в опросе.
GET /api/sse/messages cookie-сессия SSE-поток сообщений.

Вселенные и события

Публичные страницы вселенных, календаря и событий; подписка и награды — только с сессией.

Метод Путь Доступ Что делает
GET /api/universes без входа Список вселенных.
GET /api/universes/:slug без входа Одна вселенная.
POST /api/universes/:slug/follow cookie + CSRF Подписаться на вселенную.
POST /api/universes/:slug/claim-reward cookie + CSRF Забрать награду вселенной.
GET /api/calendar без входа Календарь релизов.
GET /api/events без входа Список событий.
GET /api/events/:slug без входа Одно событие.

Аниме

Плеер получает готовые ссылки на видео и проксирует субтитры. Ссылки на потоки приватные и не кэшируются: источник может требовать Referer.

Метод Путь Доступ Что делает
GET /api/anime/episodes/:id/streams без входа Плееры, качества и озвучки серии. Ответ не кэшируется.
GET /api/anime/subtitles/:id/:player/:subtitle без входа Прокси субтитров в text/vtt.

Игры

Каталог переводов внешних игр, библиотека, заявки команд и модерация. Публичные карточки читаются без входа.

Метод Путь Доступ Что делает
GET /api/games без входа Каталог игр.
GET /api/games/:id без входа Карточка игры.
GET /api/games/:id/reviews без входа Рецензии игры.
POST /api/games/:id/reviews cookie + CSRF Создать рецензию.
POST /api/games/:id/rate cookie + CSRF Оценить игру.
POST /api/games/:id/download без входа + CSRF Учесть скачивание.
POST /api/games/:id/report cookie + CSRF Пожаловаться на игру.
PUT /api/games/:id/library cookie + CSRF Добавить игру в библиотеку.
DELETE /api/games/:id/library cookie + CSRF Убрать игру из библиотеки.
POST /api/games/:id/subscribe cookie + CSRF Подписаться на обновления.
DELETE /api/games/:id/subscribe cookie + CSRF Отписаться.
GET /api/games/library cookie-сессия Библиотека игр пользователя.
GET /api/games/subscriptions cookie-сессия Подписки на игры.
POST /api/games/applications cookie + CSRF Заявка команды на перевод.
GET /api/games/applications/mine cookie-сессия Мои заявки.
POST /api/games/:id/team-chat cookie + CSRF Открыть чат команды игры.

Прогрессия, задания и аркада

XP, уровни, ежедневная награда, лидерборды, задания и внутренние мини-игры. Прогресс заданий пишут серверные хуки, а не клиент.

Метод Путь Доступ Что делает
GET /api/progression cookie-сессия XP, уровень и прогресс.
GET /api/progression/daily cookie-сессия Статус ежедневной награды.
POST /api/progression/daily cookie + CSRF Забрать ежедневную награду.
GET /api/leaderboard без входа Лидерборд.
GET /api/quests cookie-сессия Ежедневные, еженедельные и разовые задания.
GET /api/arcade/state гость или вход Состояние аркады.
GET /api/arcade/leaderboard без входа Рейтинг аркады.
POST /api/arcade/jumper/start cookie + CSRF Начать забег в Jumpеr.
POST /api/arcade/jumper/finish cookie + CSRF Завершить забег.
POST /api/arcade/platformer/start cookie + CSRF Начать платформер.
POST /api/arcade/platformer/finish cookie + CSRF Завершить платформер.
POST /api/arcade/roulette/spin cookie + CSRF Крутить рулетку.
POST /api/arcade/roulette/tickets cookie + CSRF Купить билеты рулетки.
POST /api/arcade/shop cookie + CSRF Купить предмет аркады.

Гача, магазин и экономика

Монеты, предметы, подписка и коллекция персонажей. Публичные витрины читаются без входа, действия требуют сессии; баланс меняется только на сервере. Денежные POST принимают Idempotency-Key: повтор возвращает сохранённый ответ без второго списания.

Метод Путь Доступ Что делает
GET /api/gacha/banners без входа Баннеры гачи.
GET /api/gacha/pool без входа Пул текущего баннера.
POST /api/gacha/pull cookie + CSRF Сделать крутку. Idempotency-Key: повтор не тратит валюту второй раз.
POST /api/gacha/welcome-bonus cookie + CSRF Забрать приветственный бонус.
GET /api/characters cookie-сессия Коллекция персонажей.
GET /api/characters/:id cookie-сессия Один персонаж.
POST /api/characters/:id/train cookie + CSRF Тренировать персонажа.
POST /api/characters/:id/stats cookie + CSRF Прокачать статы.
POST /api/characters/:id/interact cookie + CSRF Взаимодействовать с персонажем.
GET /api/currency/balance cookie-сессия Баланс монет.
GET /api/store без входа Витрина магазина.
GET /api/subscription/status cookie-сессия Статус подписки.
POST /api/store/buy cookie + CSRF Купить предмет. Idempotency-Key: повтор вернёт ту же покупку, а не вторую.
POST /api/store/use cookie + CSRF Использовать предмет.
POST /api/store/exchange cookie + CSRF Обменять валюту.
GET /api/inventory cookie-сессия Инвентарь.
POST /api/promo/redeem cookie + CSRF Активировать промокод.
POST /api/subscription/buy cookie + CSRF Купить или продлить подписку.

Сервисные и SEO-адреса

Не JSON-API, но полезно для интеграций и ИИ: короткие ссылки, RSS и карта сайта.

Метод Путь Доступ Что делает
POST /api/shortlinks без входа + CSRF Создать или получить короткую ссылку. Лимит 20 за 10 минут.
POST /api/feedback без входа + CSRF Отправить обратную связь. Лимит 5 в час.
GET /robots.txt без входа Правила краулеров.
GET /sitemap.xml без входа Карта сайта.
GET /rss/chapters без входа RSS последних глав.
GET /rss/novels без входа RSS новых тайтлов.
GET /rss/wall без входа RSS постов стены.
GET /s/:code без входа Редирект короткой ссылки.

Staff и cron

Эти ручки не входят в публичный контракт и предназначены для админки и внешнего cron. Staff-доступ проверяет роль moderator/admin, cron — секрет X-Cron-Secret.

Метод Путь Доступ Что делает
* /api/admin/games/* staff: moderator/admin GET/POST/PUT/DELETE: игры, заявки, жалобы и загрузки.
* /api/admin/illustrations/* staff: moderator/admin GET/POST/PUT/DELETE: иллюстрации тайтлов.
* /api/admin/import/jobs* staff: moderator/admin GET/POST: импорт глав манги.
POST /api/bot/telegram/link X-Bot-Secret Подтвердить код привязки Telegram — вызывает только @lorachi_notifier_bot. Заголовок X-Bot-Secret (TELEGRAM_BOT_SECRET или токен бота). Тело: code, telegramId, telegramUsername?, telegramFirstName?.
* /api/admin/anime/* staff: moderator/admin GET/POST: импорт и скрытие аниме.
* /api/admin/title-sites/* staff: moderator/admin GET/POST/PUT/DELETE: сабдомены тайтлов.
* /api/admin/users/* staff: moderator/admin GET/POST: пользователи и бейджи; бан — только admin.
* /api/admin/economy/* staff: moderator/admin GET/POST: экономика; ручная правка — только admin.
POST /api/cron/* X-Cron-Secret Служебные cron-задачи.

Примеры DTO

Ошибка

Все ошибки JSON-API имеют один конверт. Для 429 сервер также отдаёт Retry-After.

{
  "error": {
    "code": "E_VALIDATION_ERROR",
    "message": "Проверьте поля формы",
    "details": {}
  }
}

Карточка тайтла

id — непрозрачная строка. number главы всегда строка, даже если выглядит числом.

{
  "id": "66f1c2a1b2c3d4e5f6a7b8c9",
  "type": "novel",
  "title": "Название",
  "alt": "Альтернативное название",
  "coverUrl": "https://cdn.example/cover.webp",
  "status": "ongoing",
  "ageRating": "16+",
  "isAdult": false,
  "genres": ["фэнтези"],
  "tags": [],
  "chapters": 120,
  "views": 1000,
  "ratings": { "average": 4.7, "count": 52 },
  "url": "/novel/66f1c2a1b2c3d4e5f6a7b8c9"
}

Глава

prev и next — готовые объекты главы или null; клиенту не нужно считать соседей самому.

{
  "id": "66f1c2a1b2c3d4e5f6a7b8ca",
  "number": "12.5",
  "volume": 2,
  "title": "Название главы",
  "isPaid": false,
  "isEarlyAccess": false,
  "url": "/novel/66f1c2a1b2c3d4e5f6a7b8c9/volume/2/chapter/12.5",
  "publishedAt": "2026-10-19T00:00:00.000Z",
  "prev": null,
  "next": null
}

Токены приложения

Access живёт 30 минут, refresh — 90 дней. Refresh ротируется; старый токен после обмена недействителен.

{
  "accessToken": "lra_…",
  "refreshToken": "lrr_…",
  "tokenType": "Bearer",
  "expiresIn": 1800,
  "refreshExpiresIn": 7776000,
  "user": {}
}

Сеанс

id — непрозрачная строка web:<id> или mobile:<family>. Клиент не должен разбирать её на части.

{
  "id": "mobile:2f4c…",
  "kind": "mobile",
  "kindLabel": "Приложение",
  "deviceName": "Chrome · Android",
  "ip": "203.0.113.10",
  "createdAt": "2026-10-18T10:00:00.000Z",
  "lastSeenAt": "2026-10-19T09:00:00.000Z",
  "expiresAt": "2027-01-16T10:00:00.000Z",
  "current": true
}

Для ИИ и автоматизации

  • Предпочитайте JSON-ручки HTML-страницам: не нужно разбирать вёрстку.
  • Для нового клиента используйте /api/v1: контракт версионирован и не зависит от cookie сайта.
  • id считайте непрозрачной строкой; number главы — строкой, а не числом.
  • Для списков используйте page/limit и meta.hasMore, не угадывайте конец по длине массива.
  • Staff-ручки /api/admin/* не входят в публичный контракт.