← API overview

{season}/standings.json

/api/v1/{season}/standings.json

Win/loss records, point differential, and division for one season.

Seasons

Replace {season} with one of 2026, 2025, 2024, 2023, 2022. Not every season has every endpoint — check themanifest first. If it is not listed there, the URL 404s.

Response

Every endpoint returns the same envelope. Your data is indata — data is the array itself — there is no wrapper object inside it.

{
  "schemaVersion": "1.0",
  "generatedAt": "2026-06-23T14:03:13.152995-04:00",
  "league": "PUL",
  "data": [ ... ]
}

generatedAt is a nullable ISO-8601 timestamp that may or may not carry a UTC offset — parse leniently. It is null for 2022 and 2023, which predate the pipeline that records it.

Fields

FieldTypeMeaning
abbrevstring|nullCanonical team abbreviation.
namestring|nullFull team name.
divisionstring|nullDivision name, or null in seasons that had none.
winsnumber|nullRegular-season wins.
lossesnumber|nullRegular-season losses.
pointsFornumber|nullGoals scored.
pointsAgainstnumber|nullGoals conceded.
gamesnumber|nullGames played.
winPctnumber|nullWin percentage on a 0–100 scale, e.g. 83.3 — not a 0–1 fraction.
pointDiffnumber|nullpointsFor minus pointsAgainst.
last6array|nullUp to six "W"/"L" strings for the team's most recent regular-season games, oldest first (a "T" is also possible on a tie, though that is effectively unreachable in this sport). Postseason results are excluded.

Dotted names are nested — colors.primary means{ colors: { primary } }. When the parent is a list of objects (like seasons on the manifest),seasons.season means each entry in that array has its ownseason field — access it as seasons[i].season, not seasons.season.

Examples

curl
curl -s https://pul-stats-hub.pages.dev/api/v1/2025/standings.json
JavaScript
// 2025 table, sorted by point differential
const res = await fetch('https://pul-stats-hub.pages.dev/api/v1/2025/standings.json');
const { data } = await res.json();

for (const row of [...data].sort((a, b) => b.pointDiff - a.pointDiff)) {
  console.log(`${row.abbrev} ${row.wins}-${row.losses} (${row.pointDiff > 0 ? '+' : ''}${row.pointDiff})`);
}
Python
# 2025 table, sorted by point differential
import json, urllib.request

URL = "https://pul-stats-hub.pages.dev/api/v1/2025/standings.json"
with urllib.request.urlopen(URL) as response:
    rows = json.load(response)["data"]

for row in sorted(rows, key=lambda r: r["pointDiff"], reverse=True):
    print(f'{row["abbrev"]:>4}  {row["wins"]}-{row["losses"]}  {row["pointDiff"]:+d}')

Worth knowing

  • Regular season only — postseason games are excluded from these records, so they will not reconcile with a naive count over games.json unless you filter `isPostseason`.
  • These rows only became trustworthy on 2026-07-29. Before that fix, 2024 and 2025 had postseason baked in asymmetrically.

Help us grow the archive!We're looking for volunteers to collect stats from historical game footage.