Модерация
Бан, разбан, мьют и размьют игроков вашего сервера.
Меры модерации по игроку: бан / разбан и мьют / размьют. Каждое действие
записывается в историю нарушений на владельца API-ключа (владельца сервера). Чтение текущего
статуса и истории живёт на странице Игроки
(GET /moderation, GET /violations).
Как указать игрока
Каждый эндпоинт принимает тот же сегмент {ref}, что и эндпоинты игроков — Steam64
(76561198000000000) или Discord-id с префиксом (discord:123456789012345678).
discord:-ссылка резолвится в текущего привязанного игрока (404 not_found, если привязки
нет). Корректный Steam64 принимается как есть (можно забанить Steam-id, который ещё ни разу
не заходил).
Авторизация
| Скоуп | Что даёт |
|---|---|
players:ban | POST / DELETE …/ban — бан и разбан. |
players:mute | POST / DELETE …/mute — мьют и размьют. |
Наименьшие привилегии: бот-модератор чата может держать только players:mute, без права
банить. Ключ без скоупа получает 403 insufficient_scope.
Любая запись идемпотентна — повтор бана/мьюта (или разбана/размьюта) сходится к тому же
состоянию. Можно передать Idempotency-Key, чтобы ретрай после сбоя
сети был заведомо безопасным.
Длительность
Временная мера требует duration (целое положительное) и опционального duration_unit (по
умолчанию hours). Для постоянной меры поставьте permanent: true (тогда duration
игнорируется). Нужно прислать одно из двух — тело без обоих отклоняется
(400 validation_error), а не подставляется молча.
duration_unit | Максимум (бан) | Максимум (мьют) |
|---|---|---|
minutes | 5 256 000 | 5 256 000 |
hours | 87 600 | 87 600 |
days | 3 650 | 3 650 |
months | 120 | — (для мьютов нельзя) |
Мьюты округляются вверх до целых часов
Временный мьют округляется вверх до следующего целого часа игровым сервером (чтобы
сохранённая запись и живой мьют в игре не разъезжались). Запрос duration: 90, duration_unit: "minutes" даёт мьют на 2 часа. Баны сохраняют точную присланную длительность.
POST /v1/players/{ref}/ban
Забанить игрока. Тело (все поля опциональны, кроме правила duration/permanent выше):
| Поле | Тип | Смысл |
|---|---|---|
reason | string | Показывается в записи модерации (по умолчанию «No reason provided»). |
permanent | boolean | Постоянный бан. Взаимоисключимо с duration. |
duration | integer > 0 | Длина в единицах duration_unit. |
duration_unit | minutes | hours | days | months | По умолчанию hours. |
squad_ban | boolean | Также забанить сквад игрока. Требует squad_id. |
squad_id | string (цифры) | Сквад для бана, когда squad_ban = true. |
POST /v1/players/76561198000000000/ban
Content-Type: application/json
{ "reason": "aimbot", "duration": 7, "duration_unit": "days" }Возвращает результирующий статус модерации — тот же объект, что и
GET /v1/players/{ref}/moderation:
{
"player": { "steam_id": "76561198000000000", "discord_id": "123456789012345678" },
"ban": { "banned": true, "reason": "aimbot", "permanent": false, "expires_at": "2026-07-28T…Z", "banned_at": "2026-07-21T…Z", "banned_by": { "steam_id": "76561198000000001", "discord_id": "223…", "name": null } },
"mute": { "muted": false, "permanent": false, "muted_at": null, "duration_minutes": null, "channels": [] }
}DELETE /v1/players/{ref}/ban
Разбанить игрока. Без тела. Возвращает результирующий статус (ban.banned: false). Разбан
не-забаненного игрока тоже успешен (идемпотентно).
POST /v1/players/{ref}/mute
Замьютить игрока. Тело — как у бана, без squad_ban/squad_id/months, плюс:
| Поле | Тип | Смысл |
|---|---|---|
channels | string[] | Каналы чата для мьюта — любые из Global, Local, Squad (опустите — все три). Любое другое значение отклоняется (400). |
POST /v1/players/76561198000000000/mute
Content-Type: application/json
{ "duration": 3, "duration_unit": "hours", "channels": ["Local"] }Возвращает результирующий статус (mute.muted: true, с округлённым duration_minutes и
замьюченными channels).
DELETE /v1/players/{ref}/mute
Размьютить игрока. Без тела. Возвращает результирующий статус (mute.muted: false).
Идемпотентно.
503/504 на записи мог всё-таки примениться
Запись меняет игровой сервер, затем перечитывает новое состояние, чтобы его вернуть. Если
сервер отвалится между этими шагами, вы можете получить 503 server_unavailable /
504 gateway_timeout, хотя бан/мьют уже применился. Такой ответ несёт
error.details.mutation_applied: true (и action), чтобы вы поняли, что запись прошла.
Поскольку все действия здесь идемпотентны, безопасно повторить тот же запрос (при желании —
с тем же Idempotency-Key) или сделать GET /v1/players/{ref}/moderation, чтобы сверить
реальное состояние.
Ошибки
Стандартный конверт ошибки.
| Код | Статус | Когда |
|---|---|---|
insufficient_scope | 403 | У ключа нет players:ban (роуты бана) или players:mute (роуты мьюта). |
not_found | 404 | Нет игрока по {ref} (непривязанный Discord-id). |
validation_error | 400 | Ни duration, ни permanent; длительность больше лимита юнита; squad_ban без squad_id; плохой тип поля; либо отказ на стороне игрового сервера (его сообщение — в error.details.mod_message). |
server_unavailable | 503 | Игровой сервер офлайн или недоступен (см. заметку выше). |
gateway_timeout | 504 | Сервер не ответил вовремя (см. заметку выше). |