A versioned, key-authenticated REST API for AFL match results, player statistics, team data, leaderboards, and more. All responses are JSON.
Current version: v1
Every request (except Fixture) requires an API key passed via the Authorization header as a Bearer token.
Keys are managed on the API Usage page after signing in. Get a free API key →
Header Format
Authorization: Bearer YOUR_API_KEY
Example
curl https://kaliaflstats.com/api/afl/v1/teams \ -H "Authorization: Bearer a3f9c2d1e8..."
https://kaliaflstats.com/api/afl/v1
All endpoint paths below are relative to this base. When running locally, use http://localhost:5173.
All successful responses wrap data in a consistent envelope. List endpoints include a meta object for pagination. Single-resource endpoints return { "data": { ... } }.
List Response
{
"data": [ ... ],
"meta": {
"limit": 50,
"offset": 0,
"count": 10,
"total": 142
}
}Single Resource Response
{
"data": {
"id": "sydney-swans",
"name": "Sydney Swans",
"shortName": "SYD"
}
}All list endpoints support limit and offset query parameters.
| Parameter | Default | Range | Description |
|---|---|---|---|
| limit | 50 | 1 -- 200 | Number of records to return |
| offset | 0 | 0+ | Number of records to skip |
To iterate all records, keep fetching pages until offset + meta.count >= meta.total.
# Page 1 GET /players?limit=50&offset=0 # Page 2 GET /players?limit=50&offset=50 # Page 3 GET /players?limit=50&offset=100
The player-stats and player-stats-advanced endpoints support dynamic sorting via sort_by and order query parameters.
| Parameter | Type | Description |
|---|---|---|
| sort_by | string | Column to sort by (see valid values per endpoint) |
| order | string | asc or desc (default: desc) |
# Top goal scorers in 2024, round 10 GET /player-stats?year=2024&round=10&sort_by=goals&order=desc
Error responses always include an error string.
| Status | Body | Meaning |
|---|---|---|
| 400 | {"error":"Bad request: ..."} | Invalid or malformed query parameter |
| 401 | {"error":"Unauthorized"} | Missing, invalid, or revoked API key |
| 404 | {"error":"... not found"} | Resource with the given ID does not exist |
| 429 | {"error":"Rate limit exceeded"} | Your key's request limit has been reached |
/teamsReturns all 18 AFL teams, ordered alphabetically.
Query Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| limit | integer | No | Default 50, max 200 |
| offset | integer | No | Default 0 |
Example
curl /api/afl/v1/teams -H "Authorization: Bearer YOUR_KEY"
Response
{
"data": [
{ "id": "adelaide-crows", "name": "Adelaide Crows", "shortName": "ADL" },
{ "id": "brisbane-lions", "name": "Brisbane Lions", "shortName": "BRL" }
],
"meta": { "limit": 50, "offset": 0, "count": 18, "total": 18 }
}/teams/:idReturns a single team by its slug ID.
Path Parameters
| Name | Type | Description |
|---|---|---|
| id | string | Team slug, e.g. sydney-swans |
Example
curl /api/afl/v1/teams/sydney-swans -H "Authorization: Bearer YOUR_KEY"
Response
{
"data": { "id": "sydney-swans", "name": "Sydney Swans", "shortName": "SYD" }
}/teams/:id/statsReturns aggregated team statistics per match. Each row sums all player stats for that team in a single match. Useful for comparing team-level performance across a season.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| id | string | Yes (path) | Team slug |
| year | integer | No | Filter by season year |
| round | integer | No | Filter by round |
| limit | integer | No | Default 50, max 200 |
| offset | integer | No | Default 0 |
Example
curl "/api/afl/v1/teams/sydney-swans/stats?year=2024" \ -H "Authorization: Bearer YOUR_KEY"
Response
{
"data": [
{
"matchId": 9812, "round": 5, "year": 2024,
"opponent": "Greater Western Sydney", "opponentShortName": "GWS",
"isHome": true, "teamScore": 104, "opponentScore": 87,
"kicks": 210, "handballs": 158, "disposals": 368,
"marks": 95, "goals": 16, "behinds": 8,
"tackles": 62, "hitouts": 38, ...
}
],
"meta": { "limit": 50, "offset": 0, "count": 22, "total": 22 }
}/playersReturns players ordered alphabetically. Filter by team, search by name, or filter by season year (players who appeared in at least one match that year).
Query Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| team_id | string | No | Filter by current team slug |
| name | string | No | Partial name search (case-insensitive) |
| year | integer | No | Only players who played in this season |
| limit | integer | No | Default 50, max 200 |
| offset | integer | No | Default 0 |
Examples
# Search for a player by name GET /players?name=warner # All Collingwood players who played in 2024 GET /players?team_id=collingwood&year=2024
Response
{
"data": [
{ "id": 144, "name": "Chad Warner", "currentTeamId": "sydney-swans", "onlineId": "12345" }
],
"meta": { "limit": 50, "offset": 0, "count": 1, "total": 1 }
}/players/:idReturns a single player by numeric ID.
Example
curl /api/afl/v1/players/144 -H "Authorization: Bearer YOUR_KEY"
Response
{
"data": { "id": 144, "name": "Chad Warner", "currentTeamId": "sydney-swans", "onlineId": "12345" }
}/players/:id/careerReturns career totals and per-game averages for a player across all seasons in the database.
Example
curl /api/afl/v1/players/144/career -H "Authorization: Bearer YOUR_KEY"
Response
{
"data": {
"playerId": 144,
"playerName": "Chad Warner",
"currentTeamId": "sydney-swans",
"gamesPlayed": 85,
"totals": { "kicks": 1020, "handballs": 780, "disposals": 1800, ... },
"averages": { "kicks": 12.0, "handballs": 9.18, "disposals": 21.18, ... }
}
}/players/:id/seasonReturns season totals and per-game averages for a player in a specific year.
Query Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| year | integer | Yes | Season year |
Example
curl "/api/afl/v1/players/144/season?year=2024" -H "Authorization: Bearer YOUR_KEY"
Response shape is identical to /players/:id/career but scoped to the given year.
/matchesReturns matches with scores, teams, venue, and crowd. Ordered newest first (year desc, round desc).
Query Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| year | integer | No | Filter by season year |
| round | integer | No | Filter by round (0 = finals) |
| team_id | string | No | Matches involving this team (home or away) |
| venue | string | No | Filter by venue name (exact match) |
| date_from | string | No | ISO date, e.g. 2024-01-01 |
| date_to | string | No | ISO date (inclusive) |
| limit | integer | No | Default 50, max 200 |
| offset | integer | No | Default 0 |
Examples
# All Sydney Swans matches in 2024 GET /matches?team_id=sydney-swans&year=2024 # Matches at the MCG in a date range GET /matches?venue=MCG&date_from=2024-06-01&date_to=2024-06-30 # Round 10, 2024 GET /matches?year=2024&round=10
Response
{
"data": [
{
"id": 9812, "round": 5, "year": 2024,
"homeTeam": "Sydney Swans", "homeShortName": "SYD",
"awayTeam": "Greater Western Sydney", "awayShortName": "GWS",
"homeScore": 104, "awayScore": 87,
"venue": "SCG", "date": "2024-04-20T13:45:00",
"crowd": 38214, "sourcedAt": "2024-04-21T00:12:44.231Z"
}
],
"meta": { "limit": 50, "offset": 0, "count": 9, "total": 9 }
}/matches/:idReturns a single match by numeric ID.
Example
curl /api/afl/v1/matches/9812 -H "Authorization: Bearer YOUR_KEY"
Response shape is the same as a single item from GET /matches, wrapped in { "data": { ... } }.
/player-statsReturns per-match player statistics (17 categories). Each row is one player in one match. At least one filter is recommended.
Query Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| match_id | integer | No | Filter by match ID |
| player_id | integer | No | Filter by player ID |
| year | integer | No | Filter by season year |
| round | integer | No | Filter by round |
| team_id | string | No | Filter by team slug |
| sort_by | string | No | Sort column (default: disposals) |
| order | string | No | asc or desc (default: desc) |
| limit | integer | No | Default 50, max 200 |
| offset | integer | No | Default 0 |
Valid sort_by values
kicks, handballs, disposals, marks, goals, behinds, tackles, hitouts, goal_assists, inside_50s, clearances, clangers, rebound_50s, frees_for, frees_against, afl_fantasy_pts, supercoach_pts
Examples
# All stats for a single match GET /player-stats?match_id=9812 # One player's 2024 season, sorted by fantasy points GET /player-stats?player_id=144&year=2024&sort_by=afl_fantasy_pts # Top tacklers in round 10 GET /player-stats?year=2024&round=10&sort_by=tackles&limit=10
Response
{
"data": [
{
"matchId": 9812, "playerName": "Chad Warner", "teamId": "sydney-swans",
"kicks": 18, "handballs": 14, "disposals": 32,
"marks": 6, "goals": 1, "behinds": 0,
"tackles": 5, "hitouts": 0, "goalAssists": 2,
"inside50s": 7, "clearances": 8, "clangers": 3,
"rebound50s": 1, "freesFor": 2, "freesAgainst": 1,
"aflFantasyPts": 118, "supercoachPts": 124
}
],
"meta": { "limit": 50, "offset": 0, "count": 44, "total": 44 }
}Stat Fields Reference
| Field | Description |
|---|---|
| kicks | Kicks |
| handballs | Handballs |
| disposals | Total disposals (kicks + handballs) |
| marks | Marks |
| goals | Goals scored |
| behinds | Behinds scored |
| tackles | Tackles |
| hitouts | Hitouts (ruck contests) |
| goalAssists | Goal assists |
| inside50s | Inside 50s |
| clearances | Clearances |
| clangers | Clangers (turnover errors) |
| rebound50s | Rebound 50s |
| freesFor | Frees for (free kicks awarded) |
| freesAgainst | Frees against (free kicks conceded) |
| aflFantasyPts | AFL Fantasy points |
| supercoachPts | SuperCoach points |
/player-stats-advancedReturns advanced per-match player statistics (17 categories) including contested possessions, disposal efficiency, metres gained, and more.
Query Parameters
Same filter parameters as /player-stats: match_id, player_id, year, round, team_id, sort_by, order, limit, offset.
Valid sort_by values
contested_possessions, uncontested_possessions, effective_disposals, disposal_efficiency_pct, contested_marks, goal_assists, marks_inside_50, one_percenters, bounces, centre_clearances, stoppage_clearances, score_involvements, metres_gained, turnovers, intercepts, tackles_inside_50, time_on_ground_pct
Example
# Highest metres gained in round 10, 2024 GET /player-stats-advanced?year=2024&round=10&sort_by=metres_gained&limit=10
Advanced Stat Fields Reference
| Field | Description |
|---|---|
| contestedPossessions | Contested possessions |
| uncontestedPossessions | Uncontested possessions |
| effectiveDisposals | Effective disposals |
| disposalEfficiencyPct | Disposal efficiency (percentage) |
| contestedMarks | Contested marks |
| goalAssists | Goal assists |
| marksInside50 | Marks inside 50 |
| onePercenters | One percenters |
| bounces | Bounces |
| centreClearances | Centre clearances |
| stoppageClearances | Stoppage clearances |
| scoreInvolvements | Score involvements |
| metresGained | Metres gained |
| turnovers | Turnovers |
| intercepts | Intercepts |
| tacklesInside50 | Tackles inside 50 |
| timeOnGroundPct | Time on ground (percentage) |
/player-team-assignmentsReturns player transfer and movement history. Each row represents a period at a club. An open-ended endYear: null means the player is currently at that club.
Query Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| player_id | integer | No | All clubs a player has been at |
| team_id | string | No | All players at a club |
| year | integer | No | Assignments active during this year |
| reason | string | No | Movement type: trade, rookie, delisted, etc. |
| limit | integer | No | Default 50, max 200 |
| offset | integer | No | Default 0 |
Examples
# Full club history for a player GET /player-team-assignments?player_id=144 # All trades into Collingwood GET /player-team-assignments?team_id=collingwood&reason=trade
Response
{
"data": [
{
"id": 301, "playerName": "Chad Warner", "playerId": 144,
"teamId": "sydney-swans", "teamName": "Sydney Swans",
"startYear": 2021, "endYear": null, "reason": "rookie"
}
],
"meta": { "limit": 50, "offset": 0, "count": 1, "total": 1 }
}/leaderboardsReturns the top players ranked by any basic stat column, ordered descending. Ideal for "who had the most goals in round X?" style queries.
Query Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| stat | string | Yes | Stat to rank by (see valid values below) |
| year | integer | No | Filter by season year |
| round | integer | No | Filter by round |
| team_id | string | No | Filter to a single team's players |
| limit | integer | No | Default 50, max 200 |
| offset | integer | No | Default 0 |
Valid stat values
kicks, handballs, disposals, marks, goals, behinds, tackles, hitouts, goal_assists, inside_50s, clearances, clangers, rebound_50s, frees_for, frees_against, afl_fantasy_pts, supercoach_pts
Examples
# Top 10 disposal getters in 2024 GET /leaderboards?stat=disposals&year=2024&limit=10 # Highest goal tallies in round 5 for Sydney GET /leaderboards?stat=goals&year=2024&round=5&team_id=sydney-swans
Response
{
"data": [
{ "playerId": 144, "playerName": "Chad Warner", "teamId": "sydney-swans", "value": 32 },
{ "playerId": 201, "playerName": "Marcus Bontempelli", "teamId": "western-bulldogs", "value": 31 }
],
"meta": { "limit": 10, "offset": 0, "count": 10, "total": 4820 }
}/head-to-headReturns the match history between two teams, regardless of which was home or away.
Query Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| team_a | string | Yes | First team slug |
| team_b | string | Yes | Second team slug |
| year | integer | No | Filter to a specific season |
| venue | string | No | Filter to a specific venue |
| limit | integer | No | Default 50, max 200 |
| offset | integer | No | Default 0 |
Example
# Swans vs Magpies all-time at the SCG GET /head-to-head?team_a=sydney-swans&team_b=collingwood&venue=SCG
Response is a standard paginated list of match objects (same shape as GET /matches).
/venuesReturns all venues in the database with match counts, ordered by most matches. Useful for getting valid venue values for the venue filter on other endpoints.
Example
curl /api/afl/v1/venues -H "Authorization: Bearer YOUR_KEY"
Response
{
"data": [
{ "venue": "MCG", "matchCount": 412 },
{ "venue": "Marvel Stadium", "matchCount": 298 },
{ "venue": "SCG", "matchCount": 186 }
],
"meta": { "count": 24 }
}/standingsReturns the season ladder for a given year: wins, losses, draws, points for/against, percentage, and premiership points. Ordered by premiership points then percentage.
Query Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| year | integer | Yes | Season year |
Example
curl "/api/afl/v1/standings?year=2024" -H "Authorization: Bearer YOUR_KEY"
Response
{
"data": [
{
"teamId": "sydney-swans", "teamName": "Sydney Swans", "teamShortName": "SYD",
"played": 24, "wins": 17, "losses": 6, "draws": 1,
"pointsFor": 2156, "pointsAgainst": 1742,
"percentage": 123.77, "premiershipsPoints": 70
}
],
"meta": { "year": 2024, "count": 18 }
}/tipsReturns tipster win-probability predictions for each game in a given round, sourced from Squiggle. Each row is one tipster's prediction for one match.
Query Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| year | integer | Yes | Season year |
| round | integer | Yes | Round number |
Example
curl "/api/afl/v1/tips?year=2026&round=4" -H "Authorization: Bearer YOUR_KEY"
Response
{
"data": [
{
"id": 1, "gameId": 38201, "year": 2026, "round": 4,
"hteam": "Sydney Swans", "ateam": "Collingwood",
"hconfidence": 62, "source": "Squiggle",
"syncedAt": "2026-04-06T12:00:00.000Z"
}
],
"meta": { "year": 2026, "round": 4, "count": 9 }
}/fixture PublicReturns the season fixture (schedule) sourced from the Squiggle API. This is the only endpoint that does not require authentication.
Query Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| year | integer | No | Season year (default: current year). Range: 2000 to next year. |
Example
# No auth required curl /api/afl/v1/fixture?year=2026
Response
{
"year": 2026,
"games": [ ... ] // Squiggle fixture data
}All endpoints at a glance. All require auth unless noted.
| Method | Path | Description |
|---|---|---|
| GET | /teams | List all teams |
| GET | /teams/:id | Get single team |
| GET | /teams/:id/stats | Aggregated team stats per match |
| GET | /players | List players (search, filter) |
| GET | /players/:id | Get single player |
| GET | /players/:id/career | Career totals + averages |
| GET | /players/:id/season | Season totals + averages |
| GET | /matches | List matches (filter by team, venue, dates) |
| GET | /matches/:id | Get single match |
| GET | /player-stats | Per-match player stats (sortable) |
| GET | /player-stats-advanced | Per-match advanced stats (sortable) |
| GET | /player-team-assignments | Transfer / movement history |
| GET | /leaderboards | Top players by any stat |
| GET | /head-to-head | Match history between two teams |
| GET | /venues | All venues with match counts |
| GET | /standings | Season ladder |
| GET | /tips | Win-probability tips by round |
| GET | /fixture | Season schedule (Public — no auth) |
Ready to start building?
get a free api key →