Public results API
The tournament's scoring results are available as a free, read-only JSON API so you can build your own scoreboards, overlays, dashboards, or apps on top of the live data. No API key, no sign-up, no rate-limit form to fill in — just HTTP GET.
Quick start
Every endpoint returns JSON wrapped in a { "data": … } envelope. Fetch the live standings:
curl https://dojo-hokori-meiyo-kata-tournament.pages.dev/api/public/scoreboard// Browser / Node — CORS is open, so this works from any origin
const res = await fetch("https://dojo-hokori-meiyo-kata-tournament.pages.dev/api/public/scoreboard");
const { data } = await res.json();
for (const division of data.divisions) {
console.log(division.categoryName, division.rounds);
}Endpoints
Live and final standings for every division of the active tournament.
Includes per-round results (rounds[]) and, for two-kata rounds, a per-kata score breakdown (slots[]). The primary endpoint for reusing scoring results.
Final results of past (completed) tournaments.
Same division/entry shape as the scoreboard, for events that have finished.
Mat-by-mat running order and scheduled breaks.
{ data: { tournamentId, categories[], breaks[] } }.
The list of divisions (categories) and their competitors.
{ data: { tournamentId, participantsHidden, categories[] } }.
Metadata about the active tournament (name, status, dates).
{ data: { tournament } } — tournament is null when none is active.
Scoreboard response
The shape of /api/public/scoreboard. Each division carries a frozen rounds[] array — one result per round (the pool round, any cut-down rounds, the final) that stays available even after later rounds run. Two-kata rounds expose each kata's panel scores and trimmed total via slots[].
{
"data": {
"divisions": [
{
"categoryId": "…",
"categoryName": "U12 Girls",
"matId": 2,
"status": "completed", // upcoming | live | completed
"discipline": "kata", // kata | kumite
"finalistCount": 3,
"rankingRound": { "roundNumber": 2, "kind": "final", "status": "advanced" },
"rounds": [ // frozen result per round, oldest first
{
"roundNumber": 1,
"kind": "pool", // pool | final
"advancementCount": 6, // how many advance from this round
"entries": [
{
"rank": 1,
"name": "Skylar …",
"dojo": "…",
"country": "NL",
"kata": "Heian Shodan / Heian Nidan",
"total": 43.0,
"slots": [ // present only for two-kata rounds
{ "kata": "Heian Shodan", "scores": [7.0,7.3,7.4,7.3,8.0], "total": 22.0 },
{ "kata": "Heian Nidan", "scores": [6.5,7.0,7.0,7.0,7.5], "total": 21.0 }
],
"scores": null, // 5 panel scores for single-kata rounds
"hasPerformed": true,
"isTied": false
}
]
}
],
"competitors": [ /* merged flat list (legacy) */ ],
"tiebreaks": [ /* recorded tie-offs */ ]
}
],
"teamResults": [ { "place": 1, "dojo": "…", "gold": 2, "silver": 1, "bronze": 0, "points": 8 } ],
"participantsHidden": false,
"drawsReleased": true,
"updatedAt": "2026-06-20T10:00:00.000Z",
"stateHash": "…" // changes when results change — poll on this
}
}Usage notes
- No authentication. All endpoints under
/api/public/are open and read-only. - CORS is open (
Access-Control-Allow-Origin: *) for GET, so browser apps on any domain can read the data directly. - Cached at the edge for a few seconds. Please poll no faster than once every few seconds, and use the
stateHash/updatedAtfields to detect changes instead of hammering the endpoint. - Privacy. Before names are released, or when the organisers hide participants, results come back empty (
participantsHidden: true) — handle that case. - No personal identifiers. The API never exposes internal competitor or performance IDs, nor scores for performances that are not yet locked.
This web application was built by Bitwise-Security. For more information, visit bitwise-security.nl.
