🔌 API сайта
Публичное API сайта PfauMC отдаёт данные об игроках, дуэлях, городах, путеводителе и форуме в виде JSON. Оно только для чтения: через него нельзя ничего изменить. Статья рассчитана на тех, кто пишет Discord- и Telegram-ботов, сайты и инструменты вокруг сервера.
Основы
Базовый адрес: https://auth.pfaumc.io/api/v1
- Все запросы – GET, ответы – JSON в UTF-8.
- Имена полей в snake_case, игрок везде определяется по uuid (с дефисами), поле называется id.
- Даты – ISO 8601 в UTC, например 2026-11-04T10:00:00Z.
- Мы не отдаём IP-адреса, способы входа и любые данные, которых нет на самом сайте. Данные те же, что видит гость.
- Онлайн и графики посещаемости сервера в целом смотрите на mcwatch.online.
Ошибки
Любая ошибка приходит с подходящим HTTP-кодом и телом такого вида:
{"error": "not found", "code": "not_found"}
Поле code стабильно и предназначено для программ, error – текст для человека, его формулировка может меняться.
- bad_request (400) – неверные или недостающие параметры.
- not_found (404) – игрок, город или страница не найдены.
- invalid_api_key (401) – ключ неверный или отозван.
- rate_limited (429) – превышен лимит без ключа.
- quota_exceeded (429) – исчерпана квота вашего ключа.
- internal (500) – ошибка на нашей стороне, повторите позже.
Доступ без ключа
Для разовых запросов и экспериментов ключ не нужен: лимиты рассчитаны на обычного человека с браузером. Они считаются отдельно для каждого адреса, с которого идут запросы.
- JSON-ответы API в целом: 60 запросов в минуту, короткий всплеск до 40 запросов подряд.
- Профили игроков и их статистика: 120 в минуту, всплеск до 120.
- Страницы форума и вики (HTML): 30 в минуту, всплеск до 20.
- Машинные копии (/llms.txt, /llms-full.txt, адреса с .md, /sitemap.xml): 30 в минуту, всплеск до 30.
Бот, который опрашивает API с общего хостинга или чаще раза в секунду, быстро упрётся в эти лимиты. Для такого случая существуют ключи.
API-ключи
Ключ даёт отдельную квоту под ваше приложение. Данные он не расширяет: ответы те же, что и у гостя, а личность владельца ключа не передаётся.
Где получить. Войдите на сайт и откройте настройки форума, вкладка API. Нажмите создание ключа, задайте имя (до 64 символов, например название бота). Ключ вида pfau_ и 43 символа показывается один раз: скопируйте его сразу. Потерянный ключ не восстановить, создайте новый. Там же видны префикс ключа, время последнего использования и число запросов за сегодня, а график по часам и группам методов – в разделе использования.
Как передавать. Только в заголовке:
Authorization: Bearer pfau_...
- Передавайте ключ только с сервера. Не кладите его в адрес запроса (в query он не принимается), в код сайта, мобильное приложение или репозиторий.
- Из браузера ключ не работает: CORS не разрешает заголовок Authorization. Если страница сайта должна показывать данные, ходите за ними через свой сервер.
- Скомпрометированный ключ отзовите на той же вкладке. Отзыв действует сразу, запросы с ним получат 401.
Лимиты по рангу. Количество ключей и квота зависят от вашего ранга на сервере. Квота действует на каждый ключ отдельно.
- Без подписки: 1 ключ, 120 запросов в минуту, 20 000 в сутки.
- Подписка Фанат: 2 ключа, 180 в минуту, 30 000 в сутки.
- Подписка Меценат: 3 ключа, 300 в минуту, 50 000 в сутки.
- Подписка Спонсор: 5 ключей, 600 в минуту, 125 000 в сутки.
- Персонал сервера: 10 ключей, 1200 в минуту, 500 000 в сутки.
Окно минуты – календарная минута, окно суток – сутки по UTC, после 00:00 UTC счётчик обнуляется. Отклонённые запросы в квоту не засчитываются. Если ранг понизился, существующие ключи продолжают работать с новыми лимитами, а новые можно создать, только когда ключей меньше допустимого числа.
Ключ работает на всех публичных адресах API, а также на страницах форума и вики, /llms.txt, адресах с .md и /sitemap.xml.
Заголовки лимитов
Каждый ответ на запрос с ключом содержит:
- X-RateLimit-Limit – квота в минуту.
- X-RateLimit-Remaining – сколько запросов осталось в текущей минуте.
- X-RateLimit-Reset – через сколько секунд минута закончится.
- X-RateLimit-Daily-Limit – квота в сутки.
- X-RateLimit-Daily-Remaining – сколько запросов осталось в сутках.
При ответе 429 добавляется заголовок Retry-After – число секунд, через которое можно повторить запрос. Дождитесь его и не повторяйте запрос в цикле.
Ответы 429 и 401
Лимит без ключа, код 429:
{"error": "Слишком много запросов. Для автоматического доступа нужен API-ключ: https://pfaumc.io/forum/settings?tab=api", "code": "rate_limited", "retry_after": 30, "api_key_url": "https://pfaumc.io/forum/settings?tab=api", "docs": "https://pfaumc.io/wiki/api"}
На HTML-страницах вместо JSON показывается короткая страница с тем же текстом и ссылкой.
Квота ключа исчерпана, код 429. Поле window – minute или day:
{"error": "Квота ключа исчерпана: 120 запросов в минуту", "code": "quota_exceeded", "window": "minute", "retry_after": 30}
Неверный или отозванный ключ, код 401. Запрос с таким ключом не обслуживается, даже если без ключа он бы прошёл:
{"error": "Неверный или отозванный API-ключ", "code": "invalid_api_key"}
Кеширование
Данные меняются с разной скоростью, поэтому кеш настроен по-разному, а нужные заголовки приходят в каждом ответе.
- Ответы содержат Cache-Control с max-age: профиль игрока живёт 60 секунд, список игроков 15 секунд, рейтинг дуэлей и статистика игрока 60 секунд. Повторный запрос в этот срок отправлять не нужно: берите ответ из своего кеша.
- Профиль и ряд других ответов содержат ETag. Когда срок истёк, отправьте его обратно в заголовке If-None-Match: если данные не изменились, придёт код 304 без тела.
- Ответ зависит от заголовка Accept: браузеру, который просит text/html, JSON отдаётся с отступами, остальным – сжатым. Для бота ставьте Accept: application/json.
Хороший клиент кеширует ответы по max-age и не тратит квоту на то, что не изменилось.
Эндпоинты
Все пути ниже – относительно базового адреса.
Игроки
GET /players?online=true&q=&limit= – список игроков. Параметры: online=true – только те, кто сейчас в игре; q – начало ника (короче двух символов вернёт пустой список); limit – не больше 25 при поиске. Без единого фильтра придёт 400: полный список всех игроков не отдаётся. В ответе items, у каждого игрока: id, name, online, server (на каком сервере сидит, например survival), session_started_at, skin (url и model) и roles (key, title, color, priority). Кеш 15 секунд.
GET /players/{key} – профиль игрока. Вместо key ник или uuid. Формат совместим с профилями Mojang: id, name и properties (textures с подписью), поэтому сторонние отрисовщики скинов работают без правок, в том числе для игроков без лицензии. Наши данные лежат во вложенном объекте pfaumc: skin (готовая ссылка на PNG скина 64×64), roles (все действующие роли от старшей к младшей), first_seen_at, city (id, slug, name или null), ban (действующий бан: reason и expires_at, null – навсегда; либо null, если бана нет) и violations (история банов и мутов от новых к старым: kind, reason, created_at, expires_at, status). Статус бывает active, expired или lifted. Если игрок неизвестен, придёт 404. Кеш 60 секунд, есть ETag.
GET /players/{key}/stats – то, что растёт, пока человек играет. Поля: online, last_seen_at, playtime (online_seconds, active_seconds, session_count), activity (посуточная активность за последний год в секундах, дни без игры опущены) и duels.tiers (тир по каждому киту с хотя бы одним рейтинговым матчем). Кеш 60 секунд.
Дуэли
GET /duels/leaderboard?kit= – 100 лучших игроков кита по рейтингу среди прошедших калибровку. Параметр kit – идентификатор кита (например mace или sword). Некорректный идентификатор вернёт 400, неизвестный кит – пустой список. В ответе kit и items: place, id, name, tier (от LT5 до HT1), step (от 0 до 14, для сравнения китов), tr (рейтинг внутри тира, от 0 до 100; на самом верху больше), games, placements_left. Место определяется рейтингом, а не только тиром. Кеш 60 секунд.
Города
GET /cities – список городов.
GET /cities/{slug} – страница города: описание, координаты, глава и жители.
Путеводитель
GET /guide/places – все места на карте мира: сначала продвигаемые, затем по рейтингу.
GET /guide/places/{slug} – место и последние 20 отзывов. Анонимные отзывы приходят с author равным null.
Медиа
GET /media?ids=a,b – описание до 50 файлов форума для показа: kind, status, width, height, duration_ms, loop.
GET /media/{id} – состояние одного файла: uploading, processing, ready или failed.
Мониторинг
GET /monitor – сводка онлайна сервера за текущую и прошлую неделю: средний и максимальный онлайн. Кеш 5 минут.
Форум
GET /forum/categories – разделы форума, GET /forum/categories/{key}/topics – темы раздела, GET /forum/topics/{id}/posts – сообщения темы. Видны только открытые разделы, то есть то, что доступно гостю.
Машинные копии для LLM-агентов
Для нейросетевых агентов и поисковых роботов вики и форум доступны в виде Markdown без вёрстки:
- /llms.txt – оглавление сайта: вики, форум, ссылки на копии.
- /llms-full.txt – вся вики одним файлом.
- Добавьте .md к адресу статьи вики или темы форума: например /wiki/rules.md или /forum/t/1.md.
- /sitemap.xml – карта сайта.
Адреса работают без ключа в пределах анонимных лимитов, с ключом – в пределах его квоты. Именно эта статья в Markdown: /wiki/api.md.
Правила хорошего тона
- Кешируйте ответы и учитывайте max-age.
- Не опрашивайте API чаще, чем нужно вашему приложению: для онлайна хватит раза в 15 секунд.
- Указывайте в User-Agent название и контакт вашего проекта.
- Не передавайте ключ третьим лицам. За запросы с вашим ключом отвечаете вы; если ключ утёк, отзовите его в настройках и выпустите новый.
Нужен лимит выше или метод, которого нет? Напишите в Discord.
Опубликовано
