Playbox Organizer API

Получай данные о своих играх, лигах и матчах из скрипта или со своего сервера: кто играл и как платил, таблицы, бомбардиры, голы, карточки и хайлайты. Только чтение и только твои данные.

Базовый URL: https://app.play-box.xyz/api/organizer/v1/

Первый запрос за 5 минут

  1. Получи ключ. В приложении Playbox открой «Настройки → Инструменты организатора → API-ключи → Создать ключ». Дай ключу название и отметь «Я согласен с условиями API». Ключ выглядит как pbo_xxxxxxxx.long-secret и показывается только один раз. Сохрани его в переменных окружения своего сервера.
  2. Проверь подключение.
curl -H "X-Api-Key: $PLAYBOX_KEY" https://app.play-box.xyz/api/organizer/v1/me/

Ответ 200 вернёт твой username, название ключа и дату, до которой ключ действует.

  1. Получи свои игры.
curl -H "X-Api-Key: $PLAYBOX_KEY" "https://app.play-box.xyz/api/organizer/v1/events/?from=2026-09-01&status=FINISHED"

Ключ

Что считается твоими данными

Чужая игра или лига возвращает 404, так же как несуществующая. Контакты и фото игроков не отдаются никогда.

Лимиты

60 запросов в минуту на ключ. Запрос это один вызов любого URL API с действующим ключом, включая ответы 404 и 400. Окно обнуляется в начале каждой минуты.

Заголовок ответаЗначение
X-RateLimit-Limitлимит в минуту
X-RateLimit-Remainingсколько запросов осталось в текущей минуте
X-RateLimit-Resetсекунд до обнуления окна
Retry-Afterтолько при 429: сколько секунд подождать перед повтором

Храни данные у себя и забирай только новое: свежие игры по from и матчи завершённых игр. Если выкачивать всю историю при каждом открытии сайта, лимит закончится за секунды.

Ошибки

У всех ошибок одинаковая форма. Ветвись по code, а message пиши в лог.

{"error": {"code": "invalid_parameter", "message": "from: Use YYYY-MM-DD.", "fields": {"from": "Use YYYY-MM-DD."}}}
HTTPcodeЧто делать
401not_authenticatedнет заголовка с ключом
401invalid_keyключ неверный или отозван, создай новый
401key_expiredсрок ключа истёк, создай новый
403browser_not_allowedзапрос пришёл из браузера, вызывай API со своего сервера
404not_foundобъекта нет или он не твой
400invalid_parameterневерный параметр, подробности в fields
405method_not_allowedAPI только для чтения, используй GET
429rate_limitedподожди retry_after секунд

Формат данных

Эндпоинты

GET /me/

Чей это ключ: пользователь, название ключа, срок действия, версия условий, лимиты.

GET /leagues/

Твои лиги: id, slug, name, status (active, finished, archived), format, city, date_start, date_end, teams_count, price, game_price, url.

GET /leagues/{id}/

Лига и её правила: техническое поражение, дисциплина (лимит жёлтых карточек, дисквалификации), размер заявки.

GET /leagues/{id}/table/

Турнирная таблица в том же порядке, что и в приложении: position, team, played, wins, draws, losses, goals_for, goals_against, goal_difference, points.

GET /leagues/{id}/players/

Таблица игроков: player, team, position, games, goals, assists, yellow_cards, red_cards, suspension_games_left. Сортировка по голам, затем по передачам.

GET /leagues/{id}/rosters/

Заявки команд: каждая команда со своими игроками и датой их добавления.

GET /events/

Твои игры, сначала новые. Фильтры: from, to (YYYY-MM-DD по дате начала, UTC), status (NOT_STARTED, STARTED, FINISHED, CANCELLED), league (id), format (игроков в команде, например 8). Поля: id, league_id, starts_at, ends_at, status, results_status, format, venue, is_paid, price, price_per_player, capacity, players_count, teams_count, is_ranked, is_private, url.

GET /events/{id}/

Вся игра: команды (цвет, победы, ничьи, поражения, состав), матчи со счётом и url, mvp_player_id, записи на YouTube, трансляции.

GET /events/{id}/participants/

Кто записался и как платил: player, status (In game, Late, Did not come, Invited), team_id, joined_at, payment_method (CASH, WALLET, CARD, STRIPE, APPLE_PAY, GOOGLE_PAY, TELEGRAM), paid, payment_confirmed, paid_by, amount, is_early_bird. Эти данные только для тебя: не публикуй их.

GET /events/{id}/player-stats/

Результат каждого игрока за игру: wins, draws, losses, goals, assists, goals_conceded, yellow_cards, red_cards, rating, rating_change, is_confirmed. Доступно после завершения игры.

GET /matches/{id}/

Весь матч: event_id, league_id, number, tour, starts_at, ends_at, state, teams, score, technical_defeat, referee, video_url, url, хронология timeline, серия пенальти penalty_shootout, составы lineups (кто вышел в старте, секунды на поле) и хайлайты highlights (ссылками на YouTube).

"timeline": [
  {"type": "period", "half": 1, "is_extra_time": false, "started_at": "...", "ended_at": "...", "duration_seconds": 1200},
  {"type": "goal", "game_time_seconds": 305, "team_id": 1, "player": {}, "assistant": {}, "is_own_goal": false, "youtube_url": "..."},
  {"type": "card", "game_time_seconds": 700, "team_id": 2, "player": {}, "card": "YELLOW", "reason": "Dissent"},
  {"type": "substitution", "game_time_seconds": 900, "team_id": 2, "player_out": {}, "player_in": {}, "until_end": true}
]

Примеры

Python

import os, requests

API = "https://app.play-box.xyz/api/organizer/v1"
session = requests.Session()
session.headers["X-Api-Key"] = os.environ["PLAYBOX_KEY"]

def fetch_all(path, **params):
    offset = 0
    while offset is not None:
        page = session.get(f"{API}/{path}", params={**params, "offset": offset, "limit": 100}).json()
        yield from page["results"]
        offset = page["next_offset"]

for event in fetch_all("events/", status="FINISHED", **{"from": "2026-09-01"}):
    detail = session.get(f"{API}/events/{event['id']}/").json()
    for match in detail["matches"]:
        print(event["starts_at"], match["score"], match["url"])

JavaScript (Node 18+, на сервере)

const API = "https://app.play-box.xyz/api/organizer/v1";
const headers = { "X-Api-Key": process.env.PLAYBOX_KEY };

const res = await fetch(`${API}/leagues/8/players/`, { headers });
if (!res.ok) {
  const { error } = await res.json();
  throw new Error(`${error.code}: ${error.message}`);
}
const { results } = await res.json();
console.log(results.slice(0, 10).map(r => `${r.player.username}: ${r.goals}`));

Условия использования (версия 2026-10-01)

Версии

Версия указана в URL (v1). Новые поля могут появляться в ответах без смены версии, поэтому не падай на незнакомых полях. Удалять или переименовывать поля будем только в v2, а v1 продолжит работать.