Playbox Organizer API

Čitaj podatke o svojim utakmicama, ligama i mečevima iz svoje skripte ili sa servera: ko je igrao i kako je platio, tabele, strelci, golovi, kartoni i svetli trenuci. Samo za čitanje, samo tvoji podaci.

Osnovni URL: https://app.play-box.xyz/api/organizer/v1/

Prvi zahtev za 5 minuta

  1. Nabavi ključ. U aplikaciji Playbox otvori Podešavanja → Alati organizatora → API ključevi → Napravi ključ. Daj ključu naziv i označi „Slažem se sa API uslovima“. Ključ izgleda kao pbo_xxxxxxxx.long-secret i prikazuje se samo jednom. Sačuvaj ga u promenljivim okruženja na svom serveru.
  2. Proveri vezu.
curl -H "X-Api-Key: $PLAYBOX_KEY" https://app.play-box.xyz/api/organizer/v1/me/

Odgovor 200 vraća tvoje korisničko ime, naziv ključa i datum do kog ključ važi.

  1. Preuzmi svoje utakmice.
curl -H "X-Api-Key: $PLAYBOX_KEY" "https://app.play-box.xyz/api/organizer/v1/events/?from=2026-09-01&status=FINISHED"

Ključ

Šta se računa kao tvoji podaci

Tuđa utakmica ili liga vraća 404, isto kao ona koja ne postoji. Kontakti i fotografije igrača se nikada ne vraćaju.

Ograničenja

60 zahteva u minuti po ključu. Zahtev je jedan poziv bilo kog URL-a API-ja sa važećim ključem, uključujući odgovore 404 i 400. Prozor se resetuje na početku svakog minuta.

Zaglavlje odgovoraZnačenje
X-RateLimit-Limitograničenje po minutu
X-RateLimit-Remainingpreostali zahtevi u tekućem minutu
X-RateLimit-Resetsekundi do resetovanja prozora
Retry-Aftersamo kod 429: koliko sekundi da sačekaš pre ponovnog pokušaja

Čuvaj podatke kod sebe i preuzimaj samo ono što je novo: skorašnje utakmice preko from i mečeve završenih utakmica. Ako svaki put kada se tvoj sajt otvori ponovo preuzimaš celu istoriju, ograničenje ćeš dostići za nekoliko sekundi.

Greške

Svaka greška ima isti oblik. Granaj logiku po code, a message upiši u svoj log.

{"error": {"code": "invalid_parameter", "message": "from: Use YYYY-MM-DD.", "fields": {"from": "Use YYYY-MM-DD."}}}
HTTPcodeŠta da uradiš
401not_authenticatednedostaje zaglavlje sa ključem
401invalid_keyključ je pogrešan ili opozvan, napravi novi
401key_expiredključ je istekao, napravi novi
403browser_not_allowedzahtev je stigao iz pregledača, pozivaj API sa svog servera
404not_foundobjekat ne postoji ili nije tvoj
400invalid_parameterparametar je pogrešan, detalji su u fields
405method_not_allowedAPI je samo za čitanje, koristi GET
429rate_limitedsačekaj retry_after sekundi

Format podataka

Endpointi

GET /me/

Čiji je ovo ključ: korisnik, naziv ključa, datum isteka, verzija uslova, ograničenja.

GET /leagues/

Tvoje lige: id, slug, name, status (active, finished, archived), format, city, date_start, date_end, teams_count, price, game_price, url.

GET /leagues/{id}/

Liga i njena pravila: tehnički poraz, disciplina (limit žutih kartona, suspenzije), veličina sastava.

GET /leagues/{id}/table/

Tabela u istom redosledu kao u aplikaciji: position, team, played, wins, draws, losses, goals_for, goals_against, goal_difference, points.

GET /leagues/{id}/players/

Tabela igrača: player, team, position, games, goals, assists, yellow_cards, red_cards, suspension_games_left. Sortirano po golovima, pa po asistencijama.

GET /leagues/{id}/rosters/

Sastavi timova: svaki tim sa svojim igračima i datumom kada su dodati.

GET /events/

Tvoje utakmice, od najnovije. Filteri: from, to (YYYY-MM-DD po datumu početka, UTC), status (NOT_STARTED, STARTED, FINISHED, CANCELLED), league (id), format (igrača po timu, na primer 8). Polja: 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}/

Cela utakmica: timovi (boja, pobede, nerešeno, porazi, sastav), mečevi sa rezultatom i url, mvp_player_id, YouTube snimci, prenosi uživo.

GET /events/{id}/participants/

Ko se prijavio i kako je platio: 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. Ovi podaci su samo za tebe: nemoj da ih objavljuješ.

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

Rezultat svakog igrača na utakmici: wins, draws, losses, goals, assists, goals_conceded, yellow_cards, red_cards, rating, rating_change, is_confirmed. Dostupno kada se utakmica završi.

GET /matches/{id}/

Ceo meč: event_id, league_id, number, tour, starts_at, ends_at, state, teams, score, technical_defeat, referee, video_url, url, vremenska linija timeline, izvođenje penala penalty_shootout, postave lineups (ko je počeo, sekunde na terenu) i svetli trenuci highlights (kao YouTube linkovi).

"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}
]

Primeri

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+, na serveru)

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}`));

Uslovi korišćenja (verzija 2026-10-01)

Verzije

Verzija je u URL-u (v1). Nova polja mogu da se pojave u odgovorima bez promene verzije, zato nemoj da prijavljuješ grešku na nepoznata polja. Uklanjanje ili preimenovanje polja desiće se samo u v2, a v1 će nastaviti da radi.