API Wardog Servers
Dane, na których działa ta strona, są dostępne jako darmowe API JSON tylko do odczytu: każdy serwer WARDOGS z przeglądarki w grze, odświeżany mniej więcej raz na minutę, a do tego historia graczy do wykresów i historia poszczególnych serwerów według kodu dołączenia.
Przegląd
Bazowy URL to https://api.wardogservers.com. Każda odpowiedź jest w formacie JSON, a odczyt nie wymaga klucza API.
Pełna specyfikacja jest opublikowana jako dokument OpenAPI 3.1 pod adresem https://api.wardogservers.com/openapi.json ↗. To ten dokument jest źródłem prawdy; ta strona to jego czytelne podsumowanie.
- Kolektor odpytuje przeglądarkę serwerów w grze we wszystkich regionach mniej więcej raz na minutę. Bieżący interwał jest podawany w każdej odpowiedzi jako meta.refreshSeconds.
- Żądania z przeglądarki są akceptowane tylko z wardogservers.com. Wywołuj API ze swojego serwera, bota albo skryptu, a nie ze strony internetowej w innej domenie.
- Nieznane, zduplikowane lub błędnie sformatowane parametry zapytania są odrzucane z kodem 400, a nie ignorowane, więc literówka kończy się wyraźnym błędem, zamiast po cichu zwracać wszystko.
Szybki start
Trzy żądania wystarczą do większości zastosowań: bieżące sumy, najbardziej zatłoczone serwery pasujące do filtra i jeden serwer według identyfikatora instancji.
# Bieżące sumy
curl https://api.wardogservers.com/v1/stats
# Serwery społecznościowe w Europie Zachodniej z wolnymi slotami, najpierw najbardziej zatłoczone
curl "https://api.wardogservers.com/v1/servers?region=eu-west&type=community&hideFull=true&limit=10"
# Jeden serwer według identyfikatora instancji
curl https://api.wardogservers.com/v1/servers/$ID Skrócona odpowiedź z /v1/stats wygląda tak:
{
"data": {
"serverCount": 3544,
"playerCount": 252109,
"officialServerCount": 2765,
"communityServerCount": 779
},
"meta": {
"fetchedAt": "2026-09-13T12:54:57.302Z",
"snapshotId": "95635cb938811a34…",
"refreshSeconds": 60,
"stale": false,
"requestedRegions": ["asia-east", "asia-southeast", "…"],
"observedRegions": ["asia-east", "asia-west", "…"]
}
} Endpointy
Każdy endpoint odczytu akceptuje GET i HEAD, respektuje If-None-Match i używa opisanej niżej koperty odpowiedzi.
| Endpoint | Zwraca |
|---|---|
GET /v1/servers | Lista serwerów z filtrami, sortowaniem i paginacją. |
GET /v1/servers/{id} | Jeden serwer z dodatkowymi polami szczegółów: surowe atrybuty, build, limity poziomu i gotówki. |
GET /v1/snapshot | Wszystkie serwery z bieżącego snapshotu, uporządkowane według identyfikatora instancji, bez filtrów i paginacji. Dla klientów, które trzymają całą listę i filtrują ją lokalnie. |
GET /v1/regions | Liczba serwerów i graczy w każdym regionie oraz informacja, czy dany region został odpytany i zaobserwowany w ostatnim odczycie. |
GET /v1/stats | Sumy: serwery i gracze online z podziałem na oficjalne i społecznościowe. |
GET /v1/history/players | Szeregi czasowe graczy i serwerów do wykresów. |
GET /v1/history/heatmap | Średnia wybranej metryki według dnia tygodnia i godziny (UTC) z ostatnich 28 dni. |
GET /v1/history/peaks | Rekordowe i dzienne szczyty graczy, łącznie i według typu serwera. |
GET /v1/history/servers | Serwery zapisane przez kolektor, według kodu dołączenia, od ostatnio widzianych. Pozwala znaleźć serwer, który jest teraz offline. |
GET /v1/history/servers/ranking | Ranking serwerów według uptime pomnożonego przez liczbę graczy, czyli średnia graczy z ostatniego dnia, tygodnia lub miesiąca, przy czym czas offline liczy się jako zero. |
GET /v1/history/servers/{serverId} | Gracze, szczyt, pojemność, udział uptime i mapa w każdym przedziale dla jednego serwera, według kodu dołączenia. |
GET /v1/history/servers/{serverId}/events | Dziennik zmian jednego serwera, od najnowszych: online, offline, restart oraz zmiany buildu, mapy, modyfikatorów i limitów. |
GET /readyz | 200, gdy dostępny jest świeży snapshot, 503, gdy go brakuje albo jest nieaktualny. |
GET /openapi.json | Dokument OpenAPI 3.1. |
Filtrowanie listy serwerów
Każdy parametr /v1/servers jest opcjonalny. W wartościach liczy się wielkość liter, z wyjątkiem q.
| Parametr | Wartości | Znaczenie |
|---|---|---|
q | tekst, do 200 znaków | Wyszukiwanie bez rozróżniania wielkości liter po identyfikatorze instancji, kodzie dołączenia, nazwie, regionie, numerze serwera, mapie i trybie. |
region | eu-west,eu-central | Jeden lub więcej identyfikatorów regionów, oddzielonych przecinkami. Aktualna lista jest w /v1/regions. |
type | all · official · community, domyślnie all | Serwery oficjalne, społecznościowe albo jedne i drugie. |
hideEmpty | true · false | Pomija serwery bez graczy. |
hideFull | true · false | Pomija pełne serwery, w tym 0/0. |
passwordProtected | true · false | Tylko serwery z hasłem albo tylko bez hasła. Pomiń, żeby dostać jedne i drugie. |
sort | -players · players · name · region | -players to najpierw najbardziej zatłoczone; to wartość domyślna. |
limit | 1–500, domyślnie 100 | Rozmiar strony. |
offset | 0–100000, domyślnie 0 | Przesunięcie (liczone od zera) w przefiltrowanym i posortowanym wyniku. |
Koperta odpowiedzi
Każda udana odpowiedź zawiera data i meta. Endpoint listy dodaje pagination, a endpointy historii – obiekt history opisujący okno, grupę, metrykę i rozmiar przedziału.
Sprawdź meta.stale, zanim pokażesz liczby jako aktualne. Ma wartość true, gdy zbieranie danych jest wstrzymane albo snapshot jest starszy niż refreshSeconds plus 60 sekund. Nieaktualne odpowiedzi są też wysyłane z nagłówkami Cache-Control: no-store i X-Data-Stale: true.
| Pole | Znaczenie |
|---|---|
meta.fetchedAt | Kiedy kolektor pobrał ten snapshot. |
meta.snapshotId | Identyfikator snapshotu; zmienia się za każdym razem, gdy pojawiają się nowe dane. Wysyłany też jako nagłówek X-Snapshot-Id. |
meta.refreshSeconds | Jak często kolektor odpytuje grę. Nie odpytuj częściej. |
meta.stale | Ma wartość true, gdy danych nie należy przedstawiać jako danych na żywo. |
meta.requestedRegions | Regiony, o które kolektor odpytał grę. |
meta.observedRegions | Regiony, które zwróciły co najmniej jeden serwer w tym snapshocie. |
Obiekt serwera
To skrócona postać obiektu zwracana przez /v1/servers i /v1/snapshot. /v1/servers/{id} zwraca te same pola oraz attributes, build, level i cash.
{
"id": "001ab36e-9985-4a9c-8dff-9dc137826dfe",
"serverId": "756872",
"serverIdUpdatedAt": "2026-09-13T11:14:32.995Z",
"name": "Official #4",
"nativeName": "f14859cce268",
"type": "official",
"region": "eu-south",
"players": 100,
"maxPlayers": 100,
"reservedPlayers": 0,
"passwordProtected": false,
"serverNumber": 4,
"map": { "variant": "Bakurani", "base": "Europe" },
"mode": { "experience": "Bakurani_KOTH_01", "gameMode": "GM_Session_C", "modifiers": [] },
"rulesets": ["standard"]
} | Pole | Znaczenie |
|---|---|
id | Identyfikator bieżącej instancji gry. Zmienia się po restarcie serwera, więc nie używaj go jako stałego klucza. |
serverId | Kod dołączenia z gry jako ciąg znaków: liczba dziesiętna z zachowanymi zerami wiodącymi dla serwerów oficjalnych albo UUID dla serwerów społecznościowych od patcha 0.11. Null, jeśli jeszcze nie został pobrany. |
serverIdUpdatedAt | Kiedy ostatnio sprawdzano kod dołączenia. Null zawsze, gdy serverId ma wartość null. |
name | Official #N dla serwerów oficjalnych, w przeciwnym razie zdekodowana nazwa serwera. Może być puste. |
nativeName | Surowa nazwa serwera w postaci zgłaszanej przez grę. |
type | official lub community. |
region | Identyfikator regionu, na przykład eu-west. |
players · maxPlayers · reservedPlayers | Bieżąca i maksymalna liczba graczy oraz liczba zarezerwowanych slotów. |
passwordProtected | Czy do dołączenia wymagane jest hasło. |
serverNumber | Numer oficjalnego serwera; 0 dla serwerów społecznościowych. |
map | Wariant mapy i mapa bazowa. Każde z nich może mieć wartość null. |
mode | Nazwy experience i trybu gry oraz surowe modyfikatory z plusem (+) z ciągu experience, w kolejności źródłowej. |
rulesets | standard, hardcore lub infantry-only, wyznaczane na podstawie modyfikatorów. Dokładnie ["standard"], gdy żaden nie zostanie rozpoznany. |
Historia
/v1/history/players zwraca serię kolumnową: jedną tablicę czasów rozpoczęcia przedziałów w sekundach Unix i po jednej tablicy wartości dla każdego klucza grupy, wyrównane według indeksu. Wartość null oznacza przedział, w którym nic nie zapisano, zwykle dlatego, że kolektor był wstrzymany. Pokaż lukę, nie interpoluj.
Przedziały są zapisywane raz na snapshot od momentu włączenia historii, bez uzupełniania wstecz. Przedziały minutowe są przechowywane przez 7 dni, pięciominutowe przez 90 dni, a godzinowe bezterminowo.
| Parametr | Wartości | Znaczenie |
|---|---|---|
window | 24h · 7d · 30d · 90d · 1y, domyślnie 24h | Okno kończące się teraz. Krok przedziału to 60 s dla 24h, 300 s dla 7d, 3600 s dla 30d i 90d oraz 21600 s dla 1y. |
group | total · type · region · regionType · map · ruleset, domyślnie total | Jedna seria na klucz: suma; oficjalne i społecznościowe; region; region|type; wariant mapy; albo główny zestaw reguł. |
metric | players · servers · full · empty · capacity · free, domyślnie players | players, servers, full (pełne), empty (puste), capacity (suma maxPlayers) lub free (capacity minus players). Każda wartość to średnia ze snapshotów w danym przedziale. |
GET /v1/history/players?window=24h&group=type
{
"data": {
"t": [1789217880, 1789217940, 1789218000, "…"],
"series": {
"official": [248112, 248390, null, "…"],
"community": [3902, 3911, null, "…"]
},
"peak": { "official": ["…"], "community": ["…"] }
},
"history": {
"window": "24h", "group": "type", "metric": "players",
"step": 60, "from": 1789217880, "to": 1789304280, "since": 1789257600
},
"meta": { "…": "…" }
} Dla metric=players odpowiedź zawiera też obiekt peak z najwyższą wartością z pojedynczego snapshotu w każdym przedziale. Endpoint heatmapy uśrednia metrykę według dnia tygodnia i godziny (UTC) z ostatnich 28 pełnych dni, opcjonalnie dla jednego regionu. Peaks podaje najwyższą liczbę graczy z pojedynczego snapshotu, łącznie i według typu – rekordową oraz dla każdego z ostatnich 30 dni UTC.
Historia poszczególnych serwerów
Kluczem historii poszczególnych serwerów jest kod dołączenia, który – w przeciwieństwie do identyfikatora instancji – przetrwa restarty i zmiany map. /v1/history/servers/{serverId} zwraca wyrównane tablice: średnią liczbę graczy i najwyższy pojedynczy odczyt w czasie, gdy serwer był na liście, jego limit graczy, odsetek odczytów w przedziale, w których był na liście (jego uptime, od 0 do 1), oraz mapę na końcu przedziału, więc kolejne wartości mapy dają rotację. Zapis zaczyna się, gdy kod zostanie zobaczony po raz pierwszy, bez uzupełniania wstecz, a do tego czasu trasa zwraca 404.
| Parametr | Wartości | Znaczenie |
|---|---|---|
window | 24h · 7d · 30d · 90d, domyślnie 24h | 24h i 7d używają pięciominutowych przedziałów przechowywanych przez 7 dni; 30d i 90d używają przedziałów godzinowych przechowywanych przez 90 dni. |
GET /v1/history/servers/756872?window=24h
{
"data": {
"server": {
"serverId": "756872",
"name": "Official #4",
"type": "official",
"region": "eu-south",
"instanceId": "001ab36e-9985-4a9c-8dff-9dc137826dfe",
"firstSeen": "2026-09-13T00:00:39.000Z",
"lastSeen": "2026-09-14T11:53:22.000Z",
"samples": 2132,
"live": true
},
"t": [1789300800, 1789301100, 1789301400, "…"],
"players": [100, 98, null, "…"],
"peak": [100, 100, null, "…"],
"capacity": [100, 100, null, "…"],
"online": [1, 0.8, null, "…"],
"map": ["Bakurani", "Bakurani", null, "…"]
},
"history": {
"window": "24h", "step": 300,
"from": 1789300800, "to": 1789387200, "since": 1789257600
},
"meta": { "…": "…" }
} /v1/history/servers/{serverId}/events tworzy dziennik zmian na podstawie kolejnych odczytów, od najnowszych: tracking_started, online, offline, restart (instancja zmieniła się bez przerwy), build (changelist), map (wariant, świat lub niebo), modifiers i limits (zakresy poziomu i gotówki, hasło i limit graczy). Każde zdarzenie zawiera at, kind oraz obiekty before i after z polami, które definiują tylko dany rodzaj zdarzenia, i null tam, gdzie nie ma wcześniejszego lub późniejszego stanu. limit przyjmuje wartości od 1 do 500, domyślnie 100.
GET /v1/history/servers/756872/events?limit=3
{
"data": {
"server": { "serverId": "756872", "name": "Official #4", "…": "…" },
"events": [
{
"at": "2026-09-14T12:40:30.000Z",
"kind": "map",
"before": { "map": "Madrid", "world": "Europe", "sky": "DayEarlyFog" },
"after": { "map": "Detroit", "world": "Europe", "sky": "DayLateGray" }
},
{
"at": "2026-09-14T09:12:04.000Z",
"kind": "restart",
"before": { "instanceId": "001ab36e-9985-4a9c-8dff-9dc137826dfe" },
"after": { "instanceId": "7c1e0b52-3d9a-4e1f-9b6e-2f4c8a9d0e11" }
},
{
"at": "2026-09-13T00:00:39.000Z",
"kind": "tracking_started",
"before": null,
"after": { "instanceId": "…", "changelist": "501228", "map": "Bakurani", "…": "…" }
}
]
},
"history": { "limit": 3, "since": 1789257600 },
"meta": { "…": "…" }
} /v1/history/servers zwraca zapisane serwery, od ostatnio widzianych. q dopasowuje kod dołączenia dokładnie albo ostatnią znaną nazwę bez rozróżniania wielkości liter, więc znajdzie serwer, który jest teraz offline; serwery na żywo mają już swój serverId w /v1/servers.
| Parametr | Wartości | Znaczenie |
|---|---|---|
q | tekst, do 200 znaków | Kod dołączenia (dopasowanie dokładne) albo ostatnia znana nazwa (bez rozróżniania wielkości liter). |
type | all · official · community, domyślnie all | Serwery oficjalne, społecznościowe albo jedne i drugie. |
limit | 1–100, domyślnie 20 | Ile serwerów zwrócić. |
Cache i odpytywanie
Każda odpowiedź zawiera ETag. Odeślij go jako If-None-Match, a niezmieniony snapshot odpowie kodem 304 bez treści, co prawie nic nie kosztuje po obu stronach. Zalecany wzorzec to odpytywanie raz na minutę z If-None-Match.
const res = await fetch('https://api.wardogservers.com/v1/snapshot', {
headers: lastEtag ? { 'if-none-match': lastEtag } : {}
});
if (res.status === 304) return; // Nic się nie zmieniło od ostatniego odczytu
lastEtag = res.headers.get('etag');
const { data, meta } = await res.json();
if (meta.stale) console.warn('stale'); // Kolektor ma opóźnienie; pokazuj dalej ostatnie znane dane Świeże odpowiedzi są przechowywane w cache na brzegu sieci przez 15 sekund, więc serie identycznych żądań są tanie. Obecnie nie ma sztywnego limitu żądań, ale odpytywanie częściej niż meta.refreshSeconds nie zwróci nowszych danych i w przyszłości może być ograniczane. Jeśli potrzebujesz całej listy, pobierz raz /v1/snapshot i filtruj lokalnie, zamiast przechodzić przez kolejne strony /v1/servers.
Błędy
Błędy są zwracane jako JSON ze stałym kodem i czytelnym komunikatem. Komunikat może się zmienić, więc dopasowuj po kodzie.
{
"error": {
"code": "bad_request",
"message": "An unsupported query parameter was supplied."
}
} | Status | Kiedy |
|---|---|
400 | Nieznany, zduplikowany lub nieprawidłowy parametr zapytania albo identyfikator, który nie jest UUID. |
401 | Wymagany był klucz API, a go brakowało albo był nieprawidłowy. Nie jest zwracany przy odczytach, dopóki włączony jest dostęp publiczny. |
404 | Brak serwera o tym identyfikatorze w bieżącym snapshocie, brak historii dla tego kodu dołączenia albo nieznana trasa. |
405 | Metoda inna niż GET lub HEAD. |
503 | Brak użytecznego snapshotu. Spróbuj ponownie po minucie albo gdy /readyz zwróci 200. |
Warunki korzystania
API jest darmowe dla projektów społeczności: botów na Discorda, nakładek, dashboardów, badań. Gdy pokazujesz dane publicznie, podaj źródło – Wardog Servers – z linkiem i nie przedstawiaj ich jako oficjalnych danych BULKHEAD ani Team17.
API do odczytu jest wersjonowane pod /v1. W ramach wersji mogą dochodzić nowe pola, więc toleruj klucze, których nie rozpoznajesz. Zmiany niezgodne wstecz pojawią się jako nowa wersja i najpierw zostaną ogłoszone na tej stronie.
Pytania, projekt, którym chcesz się pochwalić, albo pole, którego potrzebujesz: Discord @xcausxn.