Base URL:
http://localhost:5000
Swagger UI:
http://localhost:5000/api-docs
Защищённые endpoints требуют заголовок:
Authorization: Bearer <token>{
"firstName": "Ivan",
"lastName": "Petrov",
"nickname": "ivan",
"username": "ivan@example.com",
"city": "Moscow",
"phone": "+79990000000",
"hashed_pwd": "password123"
}Возвращает JWT и пользователя с roles.
{
"username": "ivan@example.com",
"hashed_pwd": "password123"
}Требует JWT.
Возвращает все квесты.
Возвращает квест по ID.
Организатор или администратор.
{
"title": "Night Quest",
"city": "Saint Petersburg",
"dateofstart": "2026-06-09T18:05:00.000Z",
"dateofend": "2026-06-09T20:56:00.000Z",
"deposit": "500",
"prize": "1000",
"description": "Quest description",
"taskOrderMode": "linear"
}Правила:
titleуникален;dateofendдолжен быть позжеdateofstart;- UI отправляет даты в UTC, выбранные пользователем как локальные;
taskOrderMode- порядок прохождения заданий:linear(по умолчанию) - общий порядок для всех команд; командам можно назначить индивидуальное время старта;random- каждая команда получает случайный порядок при старте;manual- порядок для каждой команды задаёт организатор (PATCH /appls/:id/settings).
Администратор или организатор игры (создатель или соорганизатор). Частичное обновление квеста.
Администратор или организатор игры (создатель или соорганизатор). Удаляет квест и заявки на него.
Администратор или создатель игры. Добавляет соорганизатора по никнейму; пользователь автоматически получает роль organizer. У игры может быть несколько организаторов - все они модерируют игру наравне с создателем (правка игры, задания, заявки, логи, публикация).
{
"nickname": "ivan"
}Администратор или создатель игры. Убирает соорганизатора.
Администратор или любой организатор игры. Публикует результаты игры: после этого участники могут смотреть итоговую таблицу и статистику.
Auth required. Статистика прохождения игры: таблица команд по заданиям, кто отправил правильный ответ (submittedBy), время на задание, итоговое время и место (place).
Время команды: baseTotalTime - чистое время прохождения, timeAdjustments - штрафы/бонусы организаторов с причинами, totalTime - итоговое время с учётом корректировок (по нему считаются места).
До публикации доступна только администратору и организаторам игры; после публикации (published: true) — всем авторизованным пользователям. В game.organizers возвращается список соорганизаторов.
Логи действий команд во время игры: старт, каждый отправленный ответ (кто, что, верный/неверный, когда), переходы между заданиями, финиш.
Администратор видит логи всех игр, организатор — только игр, которые создал сам или где он соорганизатор.
Auth required. Создаёт команду; создатель автоматически становится капитаном и получает роль team_captain. Пользователь может быть капитаном только одной команды.
{
"name": "Team name"
}Auth required. Команды, где пользователь капитан или участник.
Auth required. Информация о команде.
Только капитан. Добавляет участника по nickname (или memberId).
{
"nickname": "ivan"
}Только капитан. Удаляет участника (капитана удалить нельзя).
Auth required. Выход из команды. Капитан не может выйти — сначала нужно передать права.
Только капитан. Передаёт права капитана участнику своей команды.
{
"newCaptainId": "507f1f77bcf86cd799439011"
}Auth required. Поведение зависит от participation игры:
- командный квест (
team): заявку подаёт капитан, команда привязывается автоматически; - одиночный квест (
solo): заявку подаёт сам игрок, команда не нужна (teamName= ник игрока).
{
"gameId": "507f1f77bcf86cd799439011"
}Правила:
- командный квест: подать заявку может только капитан команды; одна команда — одна заявка на квест;
- одиночный квест: одна заявка на пользователя; команда не требуется;
- нельзя подать заявку после
dateofstart; - новая заявка получает статус
pending.
Auth required. Возвращает заявки, поданные пользователем, и заявки команд, где он участник, с данными квеста (dateofstart, dateofend, deposit, prize, published).
Администратор или организатор игры (создатель или соорганизатор). Возвращает заявки на квест.
Администратор или организатор игры (создатель или соорганизатор).
{
"status": "approved"
}Статусы: pending, approved, rejected, completed.
Администратор или организатор игры. Настройки прохождения для конкретной команды:
{
"startAt": "2026-06-09T10:05:00.000Z",
"taskOrder": ["taskId2", "taskId1"]
}startAt- индивидуальное время старта команды (линейный режим): игра стартует в 10:00, команда 1 может приступить в 10:05, вторая в 10:10.null- команда стартует вместе со всеми;taskOrder- ручной порядок заданий (режимmanual); должен включать каждое задание игры ровно один раз.
Возвращает задания квеста, отсортированные по orderIndex.
Администратор или организатор игры (создатель или соорганизатор).
{
"title": "Task 1",
"description": "<h1>Question</h1>",
"answers": ["answer", "ответ"],
"hints": ["Hint"],
"orderIndex": 0,
"timeLimit": 60
}Очков у заданий нет: победитель определяется по итоговому времени (с учётом штрафов и бонусов).
Ответы хранятся на сервере и не отправляются в endpoint текущего задания.
Возвращает задание по ID.
Администратор или организатор игры (создатель или соорганизатор). Обновляет задание.
Администратор или организатор игры (создатель или соорганизатор). Удаляет задание.
Администратор или организатор игры (создатель или соорганизатор).
{
"taskIds": ["taskId1", "taskId2"]
}Auth required.
{
"gameApplId": "507f1f77bcf86cd799439012"
}Правила:
- начать игру может любой участник команды заявки;
- заявка должна быть
approvedи привязана к команде; - текущее время должно быть в интервале
[dateofstart, dateofend); - если команде назначено индивидуальное время старта (
startAt), раньше него стартовать нельзя; - порядок заданий зависит от
taskOrderModeигры: линейный, случайный или ручной (заданный организатором); - в квесте должно быть хотя бы одно задание.
Auth required. Возвращает текущее задание без правильных ответов.
После dateofend возвращает ошибку для незавершённой игры. Если команда уже завершила все задания, endpoint возвращает итоговый статус completed.
Auth required.
{
"answer": "answer"
}Отправлять ответы могут все участники команды. В прогрессе и логах фиксируется, кто отправил ответ (submittedBy). Если любой участник ответил правильно, вся команда переходит на следующее задание.
После dateofend ответ не принимается, прогресс незавершённой игры помечается как abandoned.
Auth required. Возвращает прогресс команды (участникам команды или администратору).
Администратор или организатор игры. Штраф или бонус к итоговому времени команды:
{
"amount": 120,
"reason": "Опоздание на точку"
}amount - секунды: положительное значение добавляет время (штраф), отрицательное убавляет (бонус). Все корректировки с причинами видны в статистике игры и входят в итоговое время и место команды.
Admin only. Назначает порядок заданий для команды.
Администратор или организатор игры (создатель или соорганизатор). Возвращает результаты команд по квесту.
Все /music/* REST-маршруты (кроме публичных ниже) - для администратора
или организатора. Игроки и экран взаимодействуют через Socket.IO (не REST).
Оси независимы: при auth=open игроки входят без регистрации (по имени/коду) —
в том числе в командной игре, где команда задаётся названием прямо с телефона;
при auth=required — по аккаунту (JWT в handshake.auth.token).
REST (управление, под auth + organizer):
GET /music/games,POST /music/games,GET|PATCH|DELETE /music/games/:id- игры (создание ставитkind=guess_song,format=offline, генеритcode).POST/PATCHпринимаютparticipation(solo/team) иauth(open/required) независимо друг от друга;PATCHтакже принимаетblockOrder— перестановку блоков.GET /music/public/:code- публичная мета по коду (без auth):{ title, auth, participation }- страница игрока выбирает вход (логин vs имя).POST|PATCH|DELETE /music/games/:id/blocks[/:blockId]- блоки песен.POST|PATCH|DELETE /music/games/:id/songs[/:songId]- песни.PATCHпринимаетstartSec/endSec(отрезок),title,artistиnote— подсказку ведущему (до 500 символов): что ещё засчитывать за верный ответ. Подсказка отдаётся только этим авторизованным API и в состояние сокета не попадает.POST /music/games/:id/songs/:songId/upload- ручная загрузка аудиофайла (raw body,?ext=).POST /music/games/:id/songs/:songId/download- повторная авто-загрузка через SpotiFLAC.GET /music/search?q=- поиск песен (SpotiFLAC).GET /music/games/:id/export- выгрузка игры одним zip (песни, отрезки, подсказки, аудио). Отдаётся сContent-Lengthи без сжатия — по нему браузер считает проценты.POST /music/games/import- загрузка такого zip (raw body,application/zip).GET /music/net,GET /music/qr?text=- LAN-IP и QR для входа игроков.GET /music/spotiflac/version- версия SpotiFLAC.
Публичные (без auth, как и раздача /media):
GET /music/public/:code- мета игры по коду.GET /music/cover?url=- прокси внешней обложки (только доверенные хосты).GET /music/artwork/:songId?size=sm- обложка, вшитая в сам аудиофайл: достаётся через ffmpeg и кэшируется рядом вmedia. Запасной источник, когда внешней обложки нет или площадка без интернета.size=smдаёт 64×64 для списков.
Socket.IO события:
- игрок:
join {role:'player', code, name, teamName, playerId}(приauth=requiredимя берётся из профиля, токен — вhandshake.auth.token),player:ready,player:buzz,player:rename,player:offline. Повторныйjoinс тем жеplayerIdв лобби меняет команду и имя; в игре команда уже не меняется; - телефон до входа:
peek {code}— подписка на лобби, чтобы видеть уже созданные команды. Игроком не делает и сессию не создаёт; - экран:
join {role:'screen', gameId},screen:audio-ready,screen:ended. Получает командыcmd(play/pause/resume/playOn/fadeAndStop/stop); вplayприходит и обложка — экран кладёт её в кэш заранее, чтобы к раскрытию она была готова. Это единственный канал, где обложка появляется до ответа, и он идёт только в комнату экрана; - ведущий (JWT в
handshake.auth.token):join {role:'admin', gameId}, далееadmin:start|continue|replay|playon|correct|wrong|reveal|skip|pause|resume|reset|finish, а такжеadmin:kick {playerId}иadmin:remove-team {teamId}.reveal— «никто не угадал»: доигрывает отрезок и показывает исполнителя без начисления очков;finish— досрочные итоги, как если бы плейлист доиграли;reset— возврат в лобби со сбросом счёта; - сервер шлёт
state(публичное состояние: фаза,mode,teams[],players[],buzzed.by,anyArmed,revealGuessed),joined(сteamId/teamName),song-updated,song-progress,error-msg.
Аудиофайлы раздаются из /media/<file>. Каталог квестов /games игры guess_song не возвращает.
Admin only. Возвращает пользователей без hashed_pwd.
Auth required. Возвращает пользователя без hashed_pwd.
Auth required. Редактирование собственного профиля: firstName, lastName, nickname, city, phone. Никнейм проверяется на уникальность.
Admin only. Назначает роли пользователю.
{
"roles": ["user", "organizer"]
}Допустимые роли: user, admin, organizer, team_captain (последняя обычно выдаётся автоматически при создании команды).
400- неверные данные или бизнес-правило нарушено;401- нет или неверный JWT;403- недостаточно прав;404- ресурс не найден;409- конфликт, например дублирующийtitle;500- ошибка сервера.