index.json
/api/v1/index.json
The manifest — every endpoint that exists, per season, with status and freshness.
Response
Every endpoint returns the same envelope. Your data is indata — data is an object on this endpoint, not an array.
{
"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
| Field | Type | Meaning |
|---|---|---|
| site | string | Public site URL. |
| contact | string | Where to reach us about the API. |
| license | string | Usage terms — free with attribution. |
| endpoints.games | string | Path to the all-seasons games endpoint. |
| endpoints.teams | string | Path to the team directory. |
| seasons.season | string | Season year, e.g. "2025". |
| seasons.status | string|null | "complete", "active", or "preseason". |
| seasons.lastUpdated | string|null | ISO timestamp of the last data refresh. null for 2022 and 2023, which predate the pipeline that records it. |
| seasons.endpoints.standings | string | Path to that season's standings. Present only if the data exists. |
| seasons.endpoints.schedule | string | Path to that season's schedule. Present only if the data exists. |
| seasons.endpoints.teams | string | Path to that season's team totals. Present only if the data exists — absent for 2022. |
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 -s https://pul-stats-hub.pages.dev/api/v1/index.json// Which seasons have team totals?
const res = await fetch('https://pul-stats-hub.pages.dev/api/v1/index.json');
const { data } = await res.json();
const withTeamTotals = data.seasons
.filter((s) => s.endpoints.teams)
.map((s) => s.season);
console.log(withTeamTotals); // ["2026", "2025", "2024", "2023"]# Which seasons have team totals?
import json, urllib.request
URL = "https://pul-stats-hub.pages.dev/api/v1/index.json"
with urllib.request.urlopen(URL) as response:
data = json.load(response)["data"]
print([s["season"] for s in data["seasons"] if "teams" in s["endpoints"]])Worth knowing
- This is the only endpoint whose `data` is an object rather than an array.
- A season's `endpoints` object omits keys for data we do not have. If a key is missing, that URL 404s — we would rather 404 than return an empty array that looks like real data.
