API Документация
REST API Noema
Публичная документация REST API сайта Noema. Базовый URL: /api. Все ответы в формате JSON. Для защищённых эндпоинтов передайте JWT-токен через query-параметр token или заголовок Authorization: Bearer <token>.
Получить ссылку для входа через Discord
Возвращает OAuth-ссылку для авторизации через Discord. Поддерживает параметр return_to — путь, на который вернётся пользователь после входа.
/api/auth/loginПараметры
| Имя | В | Тип | Описание |
|---|---|---|---|
return_to | query | string | Относительный путь для редиректа после авторизации (например, /users) |
return_toquerystringОтносительный путь для редиректа после авторизации (например, /users)
Ответ
{ "url": "https://discord.com/api/oauth2/authorize?..." }OAuth-коллбек Discord
Обрабатывает ответ Discord после авторизации: создаёт или обновляет профиль, выдаёт JWT и перенаправляет на фронтенд.
/api/auth/callbackПараметры
| Имя | В | Тип | Описание |
|---|---|---|---|
code* | query | string | Временный код от Discord |
state* | query | string | Base64-объект с return_to, origin и nonce; nonce сверяется с httpOnly cookie |
coderequiredquerystringВременный код от Discord
staterequiredquerystringBase64-объект с return_to, origin и nonce; nonce сверяется с httpOnly cookie
Ответ
Redirect → /auth/callback?return_to=<path>. Токен в URL не передаётся: backend кладёт одноразовый handoff-токен в httpOnly cookie.Обмен handoff-cookie на access-токен
Вызывается фронтендом один раз на /auth/callback. Читает одноразовую httpOnly cookie, выданную коллбеком, и возвращает JWT. Cookie гасится при первом обмене, поэтому повторный вызов вернёт 401.
/api/auth/sessionОтвет
{ access_token: string, token_type: "bearer" }Информация о текущем пользователе
Возвращает полный профиль авторизованного пользователя.
/api/auth/metoken=<JWT> или заголовок Authorization: Bearer <JWT>.Параметры
| Имя | В | Тип | Описание |
|---|---|---|---|
Authorization* | header | string | Bearer <JWT> |
AuthorizationrequiredheaderstringBearer <JWT>
Ответ
User { id, discord_id, username, global_name, avatar, email, is_admin, is_on_server, ... }Выход
/api/auth/logoutОтвет
{ "message": "Logged out successfully" }Список пользователей
Публичный список участников с поиском по нику. Включает статус в Discord, роли и текущую игровую активность.
/api/users/Параметры
| Имя | В | Тип | Описание |
|---|---|---|---|
q | query | string | Поиск по username |
limit | query | integer | Количество (1–200, default: 50) |
qquerystringПоиск по username
limitqueryintegerКоличество (1–200, default: 50)
Ответ
UserPublic[] { discord_id, username, global_name, avatar, roles[], status, playing, game }Мой профиль
/api/users/metoken=<JWT> или заголовок Authorization: Bearer <JWT>.Ответ
User (полная схема)Обновить свой профиль
Обновляет публичные поля профиля. Доступно только участникам сервера.
/api/users/metoken=<JWT> или заголовок Authorization: Bearer <JWT>.Параметры
| Имя | В | Тип | Описание |
|---|---|---|---|
bio | JSON body | string | Описание профиля |
minecraft_nick | JSON body | string | Ник в Minecraft (для стенда) |
short_status | JSON body | string | Короткий статус на стенде |
stand_texture | JSON body | string|null | URL фоновой текстуры стенда |
stand_texture_scale | JSON body | number|null | Масштаб текстуры |
stand_texture_rotate | JSON body | number|null | Угол поворота текстуры |
stand_texture_scroll_x | JSON body | number|null | Горизонтальный сдвиг текстуры |
stand_texture_scroll_y | JSON body | number|null | Вертикальный сдвиг текстуры |
bioJSON bodystringОписание профиля
minecraft_nickJSON bodystringНик в Minecraft (для стенда)
short_statusJSON bodystringКороткий статус на стенде
stand_textureJSON bodystring|nullURL фоновой текстуры стенда
stand_texture_scaleJSON bodynumber|nullМасштаб текстуры
stand_texture_rotateJSON bodynumber|nullУгол поворота текстуры
stand_texture_scroll_xJSON bodynumber|nullГоризонтальный сдвиг текстуры
stand_texture_scroll_yJSON bodynumber|nullВертикальный сдвиг текстуры
Ответ
UserОчистить стенд
Сбрасывает minecraft_nick, short_status и все параметры текстуры стенда.
/api/users/me/standtoken=<JWT> или заголовок Authorization: Bearer <JWT>.Ответ
UserПодробный профиль пользователя
Расширенный публичный профиль: базовая информация, дата вступления, пригласитель, список приглашённых пользователей, игровая активность за неделю, голосовой канал.
/api/users/public/{discord_id}/detailsПараметры
| Имя | В | Тип | Описание |
|---|---|---|---|
discord_id* | path | string | Discord snowflake ID (строка) |
discord_idrequiredpathstringDiscord snowflake ID (строка)
Ответ
{ user, joined_at, referral_code, invited_by, invited_users[], weekly_games[], voice_channel }Стенд игроков
Список участников сервера с Minecraft-никами. Включает days_on_server и параметры кастомной текстуры стенда.
/api/users/standПараметры
| Имя | В | Тип | Описание |
|---|---|---|---|
limit | query | integer | Лимит (default: 100) |
limitqueryintegerЛимит (default: 100)
Ответ
StandUser[] { discord_id, username, avatar, minecraft_nick, short_status, stand_texture, days_on_server }Информация о Discord-сервере
Последний снапшот сервера: иконка, количество участников, онлайн-участники с их ролями и статусами. Кешируется на 30 секунд.
/api/analytics/server-infoОтвет
{ guild_id, name, icon_url, member_count, online_count, in_game_count, online_members[], in_game_members[], last_updated }Сводка для главной страницы
Возвращает общее количество вступивших и время последнего обновления данных.
/api/analytics/summaryОтвет
{ total_joined: number, last_updated: ISO datetime | null }Игровая активность за неделю
Агрегирует игровые сессии за 7 дней: список игр с игроками, суммарным временем и превью-изображением.
/api/analytics/weekly-gamesОтвет
{ window: "week", last_updated, items: [{ game, preview_url, total_minutes, players[] }] }Живой снапшот каналов сервера
Каналы Discord, сгруппированные по категориям. Голосовые каналы содержат список присутствующих участников.
/api/analytics/channels-liveПараметры
| Имя | В | Тип | Описание |
|---|---|---|---|
include_hidden | query | boolean | Включить скрытые каналы (default: false) |
include_hiddenquerybooleanВключить скрытые каналы (default: false)
Ответ
{ categories[], uncategorized[], stats: { total, text, voice }, last_updated }Последнее вступление на сервер
Информация о последнем вступившем участнике: аватар, статус, текущая игра.
/api/analytics/latest-joinПараметры
| Имя | В | Тип | Описание |
|---|---|---|---|
username | query | string | Поиск по имени пользователя |
usernamequerystringПоиск по имени пользователя
Ответ
{ invitee_discord_id, inviter_discord_id, joined_at, username, display_name, avatar_url, status, game }Статистика реферальной ссылки
Публичная статистика конкретного реферального кода.
/api/analytics/referral/{code}Параметры
| Имя | В | Тип | Описание |
|---|---|---|---|
code* | path | string | Реферальный код |
coderequiredpathstringРеферальный код
Ответ
{ code, username, clicks, joins, conversion_rate, browser_breakdown, os_breakdown, device_breakdown, invited_users[] }Иконки игр
Маппинг названий игр на иконки, используемые в галерее.
/api/analytics/game-icons-jsonОтвет
{ [game_name]: { name, icon, type } }Трекинг посещения страницы
Записывает аналитическое посещение: устройство, браузер, ОС, реферальный код. Вызывается автоматически при переходе на страницы сайта.
/api/analytics/trackПараметры
| Имя | В | Тип | Описание |
|---|---|---|---|
page* | JSON body | string | Путь страницы (напр. /users) |
referral_code | JSON body | string|null | Реферальный код |
screen_resolution | JSON body | string | 1920x1080 |
language | JSON body | string | Язык браузера |
timezone | JSON body | string | Часовой пояс |
pagerequiredJSON bodystringПуть страницы (напр. /users)
referral_codeJSON bodystring|nullРеферальный код
screen_resolutionJSON bodystring1920x1080
languageJSON bodystringЯзык браузера
timezoneJSON bodystringЧасовой пояс
Ответ
{ "status": "tracked", "analytics_id": 42 }Отправить баг-репорт или предложение
Принимает multipart/form-data. Лимит: 10 репортов в час. К репорту можно прикрепить скриншоты и видео.
/api/reportstoken=<JWT> или заголовок Authorization: Bearer <JWT>.Параметры
| Имя | В | Тип | Описание |
|---|---|---|---|
report_type* | form-data | string | "bug" | "suggestion" | "other" |
priority | form-data | string | "low" | "medium" | "high" | "critical" (default: medium) |
title* | form-data | string | Заголовок |
description* | form-data | string | Подробное описание |
page_url | form-data | string | URL страницы с проблемой |
files | form-data | File[] | До 5 файлов: .png/.jpg/.jpeg/.gif/.webp/.mp4/.webm, макс. 10 МБ каждый |
report_typerequiredform-datastring"bug" | "suggestion" | "other"
priorityform-datastring"low" | "medium" | "high" | "critical" (default: medium)
titlerequiredform-datastringЗаголовок
descriptionrequiredform-datastringПодробное описание
page_urlform-datastringURL страницы с проблемой
filesform-dataFile[]До 5 файлов: .png/.jpg/.jpeg/.gif/.webp/.mp4/.webm, макс. 10 МБ каждый
Ответ
BugReport { id, report_type, title, description, status, priority, attachments[], created_at }Документация актуальна для публичной части API. Некоторые служебные эндпоинты не включены в этот список.