Tournament Endpoints
Everything about a tournament: the event itself, its standings, its army lists and its battles.
List published tournaments, newest start date first. The date range is optional — leave it out and you get the most recent tournaments.
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
from | string | Optional | Only tournaments starting on or after this date. Leave out for no lower bound. |
to | string | Optional | Only tournaments starting on or before this date. Leave out for no upper bound. Give both and the window may not be longer than a year. |
status | string | Optional | Only tournaments with this status: "planned", "ongoing" or "finished". |
cursor | string | Optional | Comes from the "next" link of a previous response. You never build this yourself. |
limit | integer | Optional | Results per page. Default: 20, max: 100. |
Response Fields (per tournament)
slugstring- Short name used in the tournament web address. Use it wherever an endpoint asks for {slug}.
namestring- Tournament name.
status"planned" | "ongoing" | "finished"- Where the tournament has got to.
startDatestring (YYYY-MM-DD) | null- First day of the tournament, as a local date at the venue.
endDatestring (YYYY-MM-DD) | null- Last day of the tournament, as a local date at the venue.
descriptionstring- The description the organiser wrote, as plain text.
citystring | null- Town or city.
countrystring | null- Country name.
playersnumber- How many players are signed up.
roundsnumber- Total number of rounds, counting every stage.
battleSizenumber- Points limit per army, for example 2000.
battlePackstring | null- Name of the battle pack the tournament is played with.
organizerstring | null- Slug of the club running the tournament, or null when no club is set. Pass it to the club endpoints.See Club
tournamentOrganizers{name, playerId}[]- The people running the tournament, each with a display name and the public player id, sorted by name. These are the organisers themselves, not the club they run it for — that is organizer above. Empty when nobody is listed. Use a player id to get that player's battles.See
GET /api/v1/users/{publicId}/battles stagesStage[]- The stages the tournament is played in, in the order they run.
urlstring- Link to the tournament page on milarki.com.
Example response
{
"data": [
{
"slug": "the-behemoth",
"name": "The Behemoth",
"status": "finished",
"startDate": "2025-01-14",
"endDate": "2025-01-15",
"description": "Two days of Age of Sigmar in Hammarö.",
"city": "Hammarö",
"country": "Sweden",
"players": 6,
"rounds": 8,
"battleSize": 2000,
"battlePack": "GHB 24/25 4th",
"organizer": "boebbens-club",
"tournamentOrganizers": [
{"name": "Björn Böbb", "playerId": "T91FKD3V"},
{"name": "Sara Sköld", "playerId": "K21XQ9PB"}
],
"stages": [
{"id": "standings", "name": "Final Standings", "type": "board"},
{"id": "swiss", "name": "Swiss Stage", "type": "board", "rounds": 5},
{"id": "knockout", "name": "Knockout Stage", "type": "bracket", "rounds": 3, "players": 8}
],
"url": "https://www.milarki.com/tournaments/the-behemoth"
}
],
"next": "https://milarki.com/api/v1/tournaments?cursor=eyJpZCI6Im5leHQifQ&limit=20"
}Get one tournament. Exactly the same shape as a tournament in the list above.
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
slug | string | Required | The short name from the tournament web address. |
Response Fields
slugstring- Short name used in the tournament web address. Use it wherever an endpoint asks for {slug}.
namestring- Tournament name.
status"planned" | "ongoing" | "finished"- Where the tournament has got to.
startDatestring (YYYY-MM-DD) | null- First day of the tournament, as a local date at the venue.
endDatestring (YYYY-MM-DD) | null- Last day of the tournament, as a local date at the venue.
descriptionstring- The description the organiser wrote, as plain text.
citystring | null- Town or city.
countrystring | null- Country name.
playersnumber- How many players are signed up.
roundsnumber- Total number of rounds, counting every stage.
battleSizenumber- Points limit per army, for example 2000.
battlePackstring | null- Name of the battle pack the tournament is played with.
organizerstring | null- Slug of the club running the tournament, or null when no club is set. Pass it to the club endpoints.See Club
tournamentOrganizers{name, playerId}[]- The people running the tournament, each with a display name and the public player id, sorted by name. These are the organisers themselves, not the club they run it for — that is organizer above. Empty when nobody is listed. Use a player id to get that player's battles.See
GET /api/v1/users/{publicId}/battles stagesStage[]- The stages the tournament is played in, in the order they run.
urlstring- Link to the tournament page on milarki.com.
Returns 404 if the tournament does not exist or is not published.
Example response
{
"data": {
"slug": "the-behemoth",
"name": "The Behemoth",
"status": "finished",
"startDate": "2025-01-14",
"endDate": "2025-01-15",
"description": "Two days of Age of Sigmar in Hammarö.",
"city": "Hammarö",
"country": "Sweden",
"players": 6,
"rounds": 8,
"battleSize": 2000,
"battlePack": "GHB 24/25 4th",
"organizer": "boebbens-club",
"tournamentOrganizers": [
{"name": "Björn Böbb", "playerId": "T91FKD3V"},
{"name": "Sara Sköld", "playerId": "K21XQ9PB"}
],
"stages": [
{"id": "standings", "name": "Final Standings", "type": "board"},
{"id": "swiss", "name": "Swiss Stage", "type": "board", "rounds": 5},
{"id": "knockout", "name": "Knockout Stage", "type": "bracket", "rounds": 3, "players": 8},
{"id": "placement-5-8", "name": "Placement #5–8", "type": "bracket", "rounds": 2}
],
"url": "https://www.milarki.com/tournaments/the-behemoth"
}
}Get the standings for one stage of a tournament. A tournament can have several stages — the Swiss rounds, a knockout bracket, placement brackets — and each one has its own standings.
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
slug | string | Required | The short name from the tournament web address. |
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
stage | string | Optional | Which stage to read. Leave it out and you get the final standings once the tournament has finished, otherwise the stage that is furthest along. |
Standings come back whole — there are no pages to work through. A board is one row per player and a bracket is a handful of matches, so you always get the lot in one go.
Stage Ids
Read the ids for a tournament from its stages list rather than guessing — a tournament only has the stages it is actually set up for.
The id is what you pass here, and it never changes. The name is what to put in front of people: it is word for word the label on the tab the organiser sees in Milarki, so a screen built on the API and the tournament page itself always agree. Do not build the name yourself from the id. The same swiss id comes back as Swiss Stage in one tournament and Group Stage in another, depending on how the organiser set it up — and a scoped board can carry a label of its own on top of that.
standings— the final standings, everything merged into one table. Only once the tournament has finished.swiss— the main Swiss rounds.knockout— the knockout bracket.placement-swiss— the Swiss board played by everyone outside the knockout.placement-3,placement-5-8, and so on — the small brackets that settle the remaining places, one per band.
Response
The response tells you which stage you got, then the rows. What the rows look like depends on the stage type: a board gives you a ranked table of players, a bracket gives you the matches instead, earliest round first.
Board Rows
ranknumber | null- Placement, 1 being first.
groupstring · optionalon group stage boards- Which group the player was in, for example "Group A".
playerstring | null- The player display name.
playerIdstring | null- The public player id, when the player has one. Use it to get that player's battles.See
GET /api/v1/users/{publicId}/battles factionstring | null- Faction played.
battlePointsnumber- Battle points earned, scored the way the organiser set up.
winsnumber- Battles won.
drawsnumber- Battles drawn.
lossesnumber- Battles lost.
victoryPointsnumber- Victory points scored across every battle.
victoryPointsDiffnumber- Victory points scored minus victory points given away.
Example response — a board stage
{
"stage": {"id": "swiss", "name": "Swiss Stage", "type": "board"},
"data": [
{
"rank": 1,
"player": "Anders Larsson",
"playerId": "L80MTI4R",
"faction": "Slaves to Darkness",
"battlePoints": 92,
"wins": 4,
"draws": 0,
"losses": 1,
"victoryPoints": 121,
"victoryPointsDiff": 37
}
]
}Tournaments Played In Groups
When a tournament is set up with groups, the board gives you every group at once, ordered by group and then by position within it. Each row says which group the player was in. You know this is coming before you read a row: the stage comes back named Group Stage.
Two things about it look like mistakes and are not. Positions start again at 1 in each group, because a group really is its own board — whoever came first in Group B did not tie with whoever came first in Group A, they simply never played the same set of people. And group is absent altogether from an ordinary Swiss board, in the same way a battle only carries the scores its battle pack actually uses.
Example response — a tournament played in groups
{
"stage": {"id": "swiss", "name": "Group Stage", "type": "board"},
"data": [
{
"rank": 1,
"group": "Group A",
"player": "Anders Larsson",
"playerId": "L80MTI4R",
"faction": "Slaves to Darkness",
"battlePoints": 92,
"wins": 4,
"draws": 0,
"losses": 1,
"victoryPoints": 121,
"victoryPointsDiff": 37
},
{
"rank": 2,
"group": "Group A",
"player": "Björn Nilsson",
"playerId": "K21PQ7ZC",
"faction": "Stormcast Eternals",
"battlePoints": 78,
"wins": 3,
"draws": 0,
"losses": 2,
"victoryPoints": 104,
"victoryPointsDiff": 12
},
{
"rank": 1,
"group": "Group B",
"player": "Cecilia Berg",
"playerId": "M53RTX9F",
"faction": "Cities of Sigmar",
"battlePoints": 88,
"wins": 4,
"draws": 1,
"losses": 0,
"victoryPoints": 118,
"victoryPointsDiff": 41
}
]
}Bracket Matches
roundstring- Name of the bracket round, for example "Quarter-finals" or "Final".
tablenumber- Table number.
playersstring[]- The two player names. Empty while the match is still waiting on an earlier result.
winnerstring | null- Name of the player who went through. Null until the match has been played.
battlestring | null- Battle id to pass to /battles/{id}. Null when no battle was recorded for the match.See Battle
An unknown stage returns 404 with a message listing the ids this tournament does have.
Example response — a bracket stage
{
"stage": {"id": "knockout", "name": "Knockout Stage", "type": "bracket"},
"data": [
{
"round": "Quarter-finals",
"table": 1,
"players": ["Anders Larsson", "Björn Nilsson"],
"winner": "Anders Larsson",
"battle": "000b1161c8a864a1f75f"
},
{
"round": "Semi-finals",
"table": 1,
"players": [],
"winner": null,
"battle": null
}
]
}Everybody taking part, in alphabetical order, each with the army list they submitted. This is the same data as the army list export in the admin.
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
slug | string | Required | The short name from the tournament web address. |
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
cursor | string | Optional | Comes from the "next" link of a previous response. |
limit | integer | Optional | Results per page. Default: 20, max: 100. |
Response Fields (per participant)
playerstring- The player display name.
playerIdstring | null- The public player id, when the player has one. Use it to get that player's battles.See
GET /api/v1/users/{publicId}/battles clubstring | null- The club the player represents, as its short name from the club web address.See
GET /api/v1/clubs/{slug} groupstring | null- Which group the player was placed in, for example "Group A". Null unless the tournament has a group stage. Matches the group on a leaderboard row.See Leaderboard row
droppedboolean- True when the player is no longer taking part, either because they dropped out or never turned up.
finalPlacementnumber | null- Where the player finished, 1 being the winner. Settled once the tournament finishes; null while it is still running, and null for tournaments that finished before we started recording it.
listArmyList | null- The army the player submitted, or null when they submitted none.
Example response
{
"data": [
{
"player": "Anders Larsson",
"playerId": "L80MTI4R",
"club": "stockholm-warlords",
"group": "Group A",
"dropped": false,
"finalPlacement": 1,
"list": {
"faction": "Disciples of Tzeentch",
"subFaction": "Guild of Summoners",
"points": 1990,
"battleTacticCards": ["Sever the Head", "Bring it Down"],
"text": "Allegiance: Disciples of Tzeentch\n..."
}
}
],
"next": null
}Every battle played in the tournament, newest first.
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
slug | string | Required | The short name from the tournament web address. |
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
cursor | string | Optional | Comes from the "next" link of a previous response. |
limit | integer | Optional | Results per page. Default: 20, max: 100. |
Response Fields (per battle)
idstring- The battle id. Pass it to /battles/{id}.
datestring (YYYY-MM-DD) | null- The day the battle was played, as a local date.
tournamentstring | null- Slug of the tournament the battle belongs to. Null for a casual battle.See Tournament
stagestring | null- Id of the tournament stage the battle was played in, for example "swiss". Null for a casual battle.See Stage
roundnumber | null- Round number, counting from 1.
scenariostring | null- Scenario played.
battlePackstring | null- Name of the battle pack the battle was played with.
battleSizenumber- Points limit per army, for example 2000.
winnerstring | null- Name of the winning player. Null on a draw and on a battle with no result yet.
victorySize"major" | "minor" | null- How big the win was.
playersBattlePlayer[]- The two players and how they scored.
urlstring- Link to the battle page on milarki.com.
Example response
{
"data": [
{
"id": "000b1161c8a864a1f75f",
"date": "2025-01-14",
"tournament": "the-behemoth",
"stage": "swiss",
"round": 3,
"scenario": "Lines of Communication",
"battlePack": "GHB 24/25 4th",
"battleSize": 2000,
"winner": "Anders Larsson",
"victorySize": "major",
"players": [
{
"player": "Anders Larsson",
"playerId": "L80MTI4R",
"faction": "Disciples of Tzeentch",
"subFaction": "Guild of Summoners",
"outcome": "win",
"battlePoints": 20,
"victoryPoints": 28,
"objectivePoints": 18,
"battleTacticsScored": 3,
"drops": 6,
"role": "defender",
"metrics": {}
}
],
"url": "https://www.milarki.com/battles/000b1161c8a864a1f75f"
}
],
"next": null
}