1. Overview
An HTTP API for reading and updating n01 tournaments, leagues, matches, team orders, and tournament statistics from external systems.
- The data retrieval APIs require no authentication. They only return the same data that is visible on the public pages (non-public items are never returned, and lists exclude private/deleted items). With Basic authentication they also return the administration items of the tournaments and leagues you administer (see 5. Authentication).
- The create, update and delete APIs require Basic authentication, and only work on the tournaments and leagues you administer (see 5. Authentication).
- All responses are JSON. On success the response is
{"result":0, ...}, on failure it is{"result":<negative value>, "error":"..."}(see 7. Result codes). - The base URL is
https://push.n01darts.com/api/v1(e.g.https://push.n01darts.com/api/v1/tournament/list). - CORS is enabled, so the API can be called directly from JavaScript in a browser.
2. Data retrieval APIs (authentication optional)
The retrieval APIs work without Basic authentication (only autopilot/get, autopilot/list
and team/player/list?all=1 need Basic authentication as an administrator). When it is supplied, the tournaments and
leagues that the authenticated user administers also include admin_id,
admin_name, join_pass and scorer_pass (always in tournament/get /
league/get; in the list APIs only when requested explicitly with fields=), and the lists include
your own private competitions (see 5. Authentication). Wrong credentials are
rejected with result: -40. After repeated failures (20 within 10 minutes for the same
address and user name) further attempts are refused for a while, even with the correct password.
GET/api/v1/health
Health check. Returns the server status.
GET/api/v1/tournament/list
Returns the list of tournaments. Private and deleted tournaments are excluded.
With Basic authentication the private competitions you administer are included as well
(use owner=1 to list only the tournaments you administer).
Use the common list parameters for filtering, sorting, and paging.
| Filterable fields | tdid lgid title t_date status kind softdarts league game_type createTime updateTime |
|---|---|
| keyword | Keyword search on the title (space-separated words are ANDed) |
| Sortable fields | createTime (default, descending) updateTime t_date status title |
| Default fields returned | tdid lgid createTime updateTime title t_date status kind |
Additional fields via fields | The above plus softdarts league game_type details image color theme theme_css oom win_lose sd_legs |
GET /api/v1/tournament/list?status__in=20,30&sort=createTime&order=desc&count=20
{"result":0, "list":[
{"tdid":"...", "lgid":"...", "createTime":1700000000, "updateTime":1700000001000,
"title":"Spring Open", "t_date":1775001600, "status":30, "kind":"darts"},
...
]}
GET/api/v1/tournament/get
Returns the full data of a single tournament.
tdid | Required. Tournament ID |
|---|---|
entry | Pass 0 to omit entry_list (included by default) |
The response's tournament contains the tournament document (including the bracket
table and settings). Non-public items are never included. When you fetch a tournament
you administer with Basic authentication, admin_id, admin_name,
join_pass and scorer_pass are included as well.
The response also has url, the page that participants and spectators open
(https://n01darts.com/n01/tournament/comp.php?id=<tdid>, or
https://n01darts.com/n01/league/season.php?id=<tdid> for an event of a league).
{"result":0, "tournament":{...}, "url":"https://n01darts.com/n01/tournament/comp.php?id=t_Ab1c_2345"}
GET/api/v1/tournament/entry/list
Returns the entry list. tdid is required.
Each entry has tpid and name, plus sns_type join
startScore c (country) index when set. Non-public items are
never returned. With the Basic authentication of an administrator of the tournament each entry also carries
pass_set (0 / 1), whether an individual password is set (the password itself is never returned;
the entry_list of /api/v1/tournament/get behaves the same).
GET/api/v1/tournament/stats
Returns the tournament statistics. tdid is required.
kind |
stats_list (default) — per team/player statisticsplayer_stats_list — per individual player statistics (team events)player_high_out — high outsplayer_high_in — high insplayer_best_leg — best legsrr_stats_list — player statistics per round robin blocklg_stats_list — player statistics per league division
|
|---|
The statistics are identical to the ones shown on the stats pages. The data is returned in the
response's stats.
GET/api/v1/league/list
Returns the list of leagues. Private and deleted leagues are excluded. With Basic authentication
the private leagues you administer are included as well (use owner=1 to list only the leagues you administer).
| Filterable fields | lgid title status createTime updateTime |
|---|---|
| keyword | Keyword search on the title |
| Sortable fields | createTime (default, descending) updateTime title status |
| Default fields returned | lgid createTime updateTime title status |
Additional fields via fields | The above plus details image theme theme_css ad |
GET/api/v1/league/get
Returns the full data of a single league. lgid is required.
As with tournaments, non-public items are never included.
The response also has url, the league portal page
(https://n01darts.com/n01/league/portal.php?lgid=<lgid>).
{"result":0, "league":{...}, "url":"https://n01darts.com/n01/league/portal.php?lgid=lg_Ab1c_2345"}
GET/api/v1/league/entry/list
Returns the league entry list. lgid is required.
Each entry has lpid and name, plus c and sns_type when set.
GET/api/v1/league/tournament/list
Returns the list of events (tournaments) that belong to a league. lgid is required.
The parameters are the same as /api/v1/tournament/list, except owner and admin_id,
which do not apply here (they are ignored).
Like the league portal, private events of the league are included (deleted ones are excluded).
GET/api/v1/match/list
Returns the list of matches. Private and deleted matches are excluded. By default the archive is searched (all matches, including ones in progress, are kept in sync there).
| Filterable fields | mid tdid tmid schid scid match_type endMatch endSchedule relayMode title startTime |
|---|---|
player | Partial, case-insensitive match on player names. Must be combined with tdid (-51 without it) |
live | Pass 1 to search only matches in progress (not yet moved to the archive) |
| Sortable fields | startTime (default, descending) updateTime |
| Default fields returned | mid tdid tmid schid scid match_type title startTime endMatch statsData |
Additional fields via fields | The above plus endSchedule relayMode settings currentSet currentLeg updateTime |
match_type is "01" or "cricket". Matches without it are 01 matches.
GET/api/v1/match/get
Returns the full data of a single match, including per-leg scores. mid is required.
The archive is searched first; when the match is not there, the matches in progress are searched.
Deleted matches are not returned. A private match (private = 1) is returned only to the
administrator of the tournament it belongs to (Basic authentication); otherwise -1 is returned.
Non-public items are never included. SNS-related IDs inside statsData are masked to
"1" (presence only).
GET/api/v1/team/order/list
Returns the team orders of a team event.
tdid | Required. Tournament ID |
|---|---|
tmid tpid schid | Optional filters |
Each element has tmid tpid schid and fix (whether the
order is fixed). When an order has been submitted it also has order (the lineup;
oid opid oname are complemented from the team player list), and
res when a result has been entered.
GET/api/v1/team/player/list
Returns the team players. tdid is required, tpid is optional (all teams
when omitted). Deleted players are excluded. Each player has tpid oid
opid oname, plus index when it is set (players without an index come last).
With all=1 the deleted players are returned as well, each with delete
(this needs Basic authentication as an administrator of the tournament).
GET/api/v1/tournament/standings
Returns the standings of the league (lg) and round robin (rr) groups. tdid is required.
The ranks are computed with the same rules as the pages (points, Buchholz, win/loss difference, leg difference and head-to-head).
A tournament with neither a league nor a round robin format returns result: -51.
{"result":0, "tdid":"...", "groups":[
{"kind":"lg", "index":0, "title":"Division 1", "players":[
{"tpid":"aaaa", "name":"Player One", "rank":1, "p":3, "w":3, "d":0, "l":0, "diff":6, "diff_l":0, "pts":6, "bh":4, "byes":0},
...
]}
]}
players is ordered by rank. Players who have not played yet have rank 0 and come last.
p played / w d l won, drawn, lost / diff leg difference (set difference in a set format) /
diff_l leg difference of a set format / pts points / bh Buchholz (swiss, when enabled) / byes number of byes.
The points include the manual bonus points of the management screen (lg_pts, rr_pts for a round robin with the
point system), the bonus points of a result (add) and the points per game of a team event (pt), like the standings
of the pages. A round robin without the point system is ranked by win lose leg_win leg_lose
and has no pts.
GET/api/v1/tournament/end_group
Returns whether every match of each round robin block (rr_<index>) and league division (lg_<index>)
has finished (1 = finished, 0 = not yet). Use it before assigning the qualifiers to the final bracket.
{"result":0, "tdid":"...", "groups":{"rr_0":1, "rr_1":0}}
GET/api/v1/league/schedule/get
Returns the fixtures (match cards) of the league format. tdid is required, div (division index) is optional
(without it one array per division is returned).
{"result":0, "tdid":"...", "swiss":0, "schedule":[
[{"p":["aaaa","bbbb"], "lsid":"ab3f", "t":""}, {"p":["cccc","dddd"], "lsid":"k9x2", "t":"", "r":1}],
[]
]}
| Field | Meaning |
|---|---|
p | The two tpid of the card. "" is an empty slot, "empty" a bye |
lsid | Card ID (4 characters). The result is stored in lg_result["<div>_<lsid>"] |
t | Card title |
r | Swiss round number (1-based) |
For a swiss league swiss is 1 and rounds carries, per division, the current round (round),
the total number of rounds (total), the unassigned slots of the current round (blank) and the player count (members).
GET/api/v1/league/stats
Returns the statistics of a league (all its events). lgid is required.
kind is stats_list (default), player_stats_list, rank_list or t_list;
the same JSON as the league statistics page is returned in stats.
GET/api/v1/autopilot/get
Returns the autopilot (automatic board assignment) settings and the status written by the autopilot server. tdid is required and
the Basic authentication of an administrator of the tournament is needed.
{"result":0, "tdid":"...",
"config":{"tdid":"...", "lgid":"...", "group":"...", "name_control":0, "name_mode":"auto", "priority":0, "hold_robin":0,
"types":{"t":{"badge_number":"1-10", "break_time":0, "round":0, "enable":1}, "s2":{...}, "dw":{...}, "dl":{...}},
"remove_old_badge":1, "set_referee":0, "referee_type":"same_board", "updateTime":1700000000000},
"status":{"time":1700000000000, "error":"", "held":{...}}}
config is null when nothing has been set. status.held lists the matches the server did not assign a board to
(with the reason: opponent undecided, waiting for a board, player busy or on a break), the same list as the settings page.
GET/api/v1/autopilot/list
Returns the autopilot settings and status of every event of a league. lgid is required and the Basic authentication of an
administrator of the league is needed. Each item has tdid title status (tournament state) and
config / status as above.
3. Common list parameters
The list APIs (.../list) accept the following query parameters so that many conditions
can be combined freely.
| Parameter | Meaning | Example |
|---|---|---|
<field>=<value> | Equals | status=30 |
<field>__ne=<value> | Not equal | match_type__ne=cricket |
<field>__gt / __gte=<value> | Greater than / or equal | startTime__gte=1700000000 |
<field>__lt / __lte=<value> | Less than / or equal | updateTime__lt=1700000000000 |
<field>__in=<v,v,...> | Matches any of the values | status__in=20,30 |
<field>__nin=<v,v,...> | Matches none of the values | status__nin=40 |
<field>__exists=0|1 | Whether the field exists | lgid__exists=1 |
<field>__regex=<text> | Partial match, case-insensitive (string fields only) | title__regex=open |
keyword=<word word...> | Keyword search on the title (tournament / league). Up to 8 words of 100 characters each | keyword=summer%20cup |
owner=1 | Only the tournaments / leagues you administer (tournament / league). Requires Basic authentication | owner=1 |
admin_id=<id> | Filter by administrator (tournament / league). Requires Basic authentication; only your own admin_id is accepted (admin_id=me means your own admin_id) | admin_id=twid:12345 |
player=<name> | Partial match on player names (match). 2 to 100 characters. tdid is required | tdid=XXXX&player=alice |
sort=<field> | Sort field | sort=startTime |
order=asc|desc | Sort order (default desc) | order=asc |
skip=<n> | Number of items to skip (up to 100000) | skip=100 |
count=<n> | Number of items to return (capped; default/cap is 100) | count=50 |
fields=<field,...> | Select the fields to return (public fields; with Basic authentication admin_id admin_name join_pass scorer_pass may be selected too for the competitions you administer) | fields=tdid,title,status |
fields.
An unknown sort or fields name, an unknown __ operator, or a value that does not fit the
field type is rejected with result: -51; a filter parameter whose field is not listed is ignored (it does not
narrow the result), so check the spelling of your filters. The time fields createTime, t_date and
startTime are seconds; updateTime is milliseconds.
Multiple conditions can be combined on the same field
(e.g. startTime__gte=...&startTime__lt=...).
4. Data structures
The JSON returned by the API mirrors n01's internal data. This chapter describes the main fields (fields that are not listed are used internally by the system). The update APIs take the same structures.
4.1 Identifiers
| ID | Description |
|---|---|
tdid | Tournament ID, issued when the tournament is created and contained in its URL (e.g. t_Ab1c_2345) |
lgid | League ID (e.g. lg_Ab1c_2345). Events that belong to a league carry it |
The web page of a competition cannot be derived from its ID alone (a tournament and an event of a league
open on different pages). tournament/get, tournament/create, league/get and
league/create return url, the page participants and spectators open, next to the document.
Use it instead of building an address from the ID. | |
tpid | Tournament player ID: a 4 character ID for one entry |
lpid | League player ID |
tmid | Tournament match ID, formatted as <tdid>_<ttype>_<round>_<tpid>_<vsTpid>
(for a league: <tdid>_lg_<division>_<round>_<tpid>_<vsTpid>). It identifies one fixture |
mid | Match ID: the game data of one set |
scid | Groups the sets of one game in a set-based match |
schid | Schedule ID: one game inside a fixture that has several games (team battles etc.) |
oid | Team member ID (unique inside a tournament). Older data may use a number |
opid | Team member number given by the organizer |
4.2 Competition types (ttype)
A tournament can hold several competition formats at the same time, each with its own settings,
bracket and results. The format is identified by its type, which forms the {ttype}_
prefix of those fields.
| ttype | Description |
|---|---|
lg | League |
rr | Round robin |
t | Single elimination 1 |
t3 | Third place match of single elimination 1 |
s2 | Single elimination 2 |
s2_3 | Third place match of single elimination 2 |
dw | Winners side of a double elimination |
dl | Losers side of a double elimination |
m | Single matches (knockout games) |
4.3 Tournament state (status)
| status | Description |
|---|---|
| 10 | Preparing |
| 20 | Accepting entries |
| 25 | Building the bracket |
| 30 | In progress |
| 40 | Finished |
4.4 Tournament (tournament)
The main fields of the document returned by /api/v1/tournament/get.
| Field | Type | Description |
|---|---|---|
tdid | string | Tournament ID |
lgid | string | ID of the league it belongs to (absent for a stand-alone tournament) |
league | number | 1: treated as an event of a league and hidden from the tournament list (the list page of the tournament area). Set to 1 when created under a league. It does not affect the filtering of /api/v1/tournament/list |
createTime | number | Creation time (UNIX time in seconds) |
updateTime | number | Update time (UNIX time in milliseconds) |
status | number | Tournament state (4.3) |
title | string | Tournament title |
t_date | number | Competition date (UNIX time in seconds), 0 when not set |
s_date | number | Date used for sorting (UNIX time in seconds). Set on creation from t_date (the creation time when t_date is not set). Updating t_date does not change it, so send both when you change the date |
details | string | Description of the competition |
image | string | URL of the title image |
color | string | Background color (used with the standard theme only) |
theme theme_css | string | Theme of the competition and the URL of a custom theme CSS |
lang | string | Display language ("" follows the browser language) |
kind | string | Kind of competition (darts, softdarts, billiards, tennis, table_tennis, football, common, or a free name) |
softdarts | number | 1: soft-tip darts |
game_type | number | Bit flags of how players take part. 1: n01 Live (local match) / 2: n01 Online / 4: submit results |
private | number | 1: hide from the public list |
ad | number | 1: show advertisements |
chat | number | 1: enable the chat |
show_avg | number | 1: show averages |
dynamic_avg | number | 1: show the dynamic average |
auto_complete | number | 1: finish the tournament automatically |
confirm_start | number | 1: players must confirm the opponent before a game |
select_first | number | 1: choose who throws first at the start (n01 Live only) |
lf | number | 1: the loser of the previous leg throws first in the next one |
win_lose | number | 1: show the result as win/lose marks (only for a single point match) |
sd_legs | number | 1: label Sets as Legs |
individual_pass | number | 1: ask for a personal password on the first participation |
hide_sns | number | 1: do not use SNS entries |
common_join | number | 1: do not pick a player when joining (anyone can enter scores) |
show_entry_no | number | 1: show numbers in the entry list |
team_games | number | 1: team battle |
name_sep | string | Separator in a name (where to break the line, for doubles etc.) |
oom | object | Ranking (order of merit) settings |
entry_list | array | Entry list (4.6), added by tournament/get only |
{ttype}_setting | object | Settings of that format (4.5) |
{ttype}_table | array | Bracket (4.5) |
{ttype}_result | array | Results (4.5) |
{ttype}_title | array | Round titles |
{ttype}_init | array | Guide (the initial bracket) |
admin_id admin_namejoin_pass scorer_pass | string | Administrator id and organizer name, join password and scorer password. Returned only when you fetch a competition you administer with Basic authentication (5. Authentication) |
4.5 Brackets and results
Each format keeps its bracket and results in its own fields. Only the formats whose
{ttype}_setting is enabled (lg_setting.league,
rr_setting.round_robin, t_setting.tournament,
m_setting.matchs and so on set to 1) are used.
| Field | Structure |
|---|---|
t_table s2_tabledw_table dl_table |
One array per round, each holding tpid values. The first round is [0],
the second [1]. A slot that is not decided yet is an empty string |
rr_table | One array per group, each holding the tpid values of that group |
lg_table | One array per division, each holding the tpid values of that division.
A bye opponent is written as "empty" |
t_result s2_resultdw_result dl_result
rr_result |
One entry per round (per group for a round robin). Each is an object keyed by tpid,
holding the result keyed by the opponent's tpid |
lg_result | An object keyed by "<division>_<lsid>" (e.g. "0_ab3f"; lsid is the 4-character ID of the match card).
Below that the structure is the same as the other formats |
rr_rank lg_rank | Manually assigned ranks |
A result ({ttype}_result[round][tpid][vsTpid]) has the following shape.
| Field | Description |
|---|---|
r | Result: the number of legs in a leg-based game, the number of sets in a set-based game |
l | Number of legs (set-based games only) |
a | Average |
t | 100+ |
t4 | 140+ |
t8 | 180's |
h | High out |
b | Best leg |
a_b | Second legs |
w_b | Break legs |
/api/v1/league/schedule/get / update / generate.
The Swiss system settings are lg_setting.swiss, swiss_rounds and
swiss_bh.
4.6 Entries
The shape of /api/v1/tournament/entry/list and of entry_list in tournament/get.
| Field | Type | Description |
|---|---|---|
tpid | string | Tournament player ID |
name | string | Player name (team name in a team battle) |
c | string | Country code |
index | number | Sort order |
join | number | Participation state (0-9; 1 = has joined). Absent when it is 0 or not set |
startScore | number | Handicap (starting score). Absent when not set |
sns_type | string | Linked SNS (t: Twitter / f: Facebook / g: Google). Absent when not linked |
4.7 League (league)
A league groups several tournaments (events). Its events are listed with
/api/v1/league/tournament/list.
| Field | Type | Description |
|---|---|---|
lgid | string | League ID |
title details | string | Title and description |
show_details | number | 1: show the description on the portal |
createTime updateTime | number | Creation time (seconds) and update time (milliseconds) |
image colortheme theme_css lang | string | Same as a tournament. theme and lang are also the defaults for new events |
sort sort_order | string / number | Order of the events (date / name / manual) and ascending (1) / descending (-1) |
private ad | number | Same as a tournament |
show_count | number | Number of events per page in the event list of the portal and the league settings (10 when missing or 0) |
A league entry (/api/v1/league/entry/list) has lpid, name, c and sns_type.
4.8 Match (match)
A match is the game data of one set. Matches in progress live in match and every
match including the finished ones in match_archive; /api/v1/match/get
looks in the archive first and falls back to the matches in progress (it has no live parameter;
live=1 exists on /api/v1/match/list only).
| Field | Type | Description |
|---|---|---|
mid | string | Match ID |
match_type | string | "01" or "cricket". A match without this field is 01 |
tdid lgid | string | Tournament ID and league ID |
tmid ttype round t_no | string / number | Fixture ID, competition type, round (0 based) and the position in the bracket (1 based) |
scid schid | string | The ID grouping the sets and the ID of the game inside the schedule |
title orgTitle | string | Title with and without the subtitle |
startTime | number | Start time (UNIX time in seconds) |
updateTime | number | Update time (UNIX time in milliseconds) |
startScore | number | Starting score (01 only) |
roundLimit maxRound | number | 0/1: whether rounds are limited, and the limit |
limitSet limitLeg | number | Number of sets and legs to win |
currentSet currentLeg | number | Current set / leg (0 based) |
drawMode | number | 0: no draw / 1: draws allowed |
endMatch | number | 0: this set is not finished / 1: finished |
endSchedule | number | 1 once every game is finished. Absent otherwise |
private | number | 1: hide from the history list |
legData | array | Per-leg data |
statsData | array | Per-player stats (the left player is [0]) |
Each element of legData (for 01) has the following shape.
| Field | Type | Description |
|---|---|---|
time | number | Start time of the leg (milliseconds) |
first | number | 0: the left player throws first / 1: the right player throws first |
endFlag | number | 0: the leg is not finished / 1: finished |
winner | number | 0: the left player won / 1: the right player won |
middleForDiddle | number | 1: the leg was decided by a middle for diddle (closest to the bull); the winner is in winner. The leg was not finished by throwing, so the statistics do not count its darts and scores. Used when the round limit is reached, but available at any time |
playerData | array | One array per player, each holding
{"score": scored, "left": remaining} per round.
On a finish the score is negative and tells the dart (-1: first / -2: second / -3: third) |
"playerData": [
[ {"score":0,"left":501}, {"score":180,"left":321}, {"score":180,"left":141}, {"score":-3,"left":0} ],
[ {"score":0,"left":501}, {"score":100,"left":401} ]
]
Each element of statsData has the following shape.
| Field | Type | Description |
|---|---|---|
name | string | Player name |
pid | string | Player ID (internal to n01) |
tpid | string | Tournament player ID |
winSets winLegs | number | Sets won (as of the start of this set) and legs won |
allScore allDarts | number | Total score and darts thrown (used for the average) |
order | array | Team battle order (4.9) |
tid, fid, gid) are masked to "1",
which only tells whether they are set. When statsData is sent to an update API, those
items keep their server-side values.
For Cricket (match_type is "cricket") each leg holds turns
(one entry per turn) instead of playerData. A turn is
{"p": player, "r": round, "h": [[number index, marks], ...]}, where the number index is
the position in [20, 19, 18, 17, 16, 15, BULL]. statsData holds
allMarks (total marks) instead of allScore.
4.9 Team members and orders
In a team battle (team_games is 1) an entry (tpid) is a team, and its
members and the order they play in each fixture are kept separately.
| Field | Description |
|---|---|
tpid | ID of the team (the entry) |
oid | Member ID, unique inside the tournament |
opid | Member number given by the organizer |
oname | Member name |
index | Sort order |
An order (/api/v1/team/order/list) is one entry per (tmid,
tpid, schid), and order holds the members playing that game in
their playing order (on retrieval oid, opid and oname are
filled in; a member that no longer exists comes back as empty strings).
fix tells whether the order is confirmed (1), and res is the result of that
game.
4.10 Doubles
Doubles can be set up in two ways. Normally the first one (one entry carrying the names of both players) is enough. When you want statistics per player (average, high finish, etc.), the second one, building the pairs as teams with a schedule, is the effective way.
| Way | Entry | Statistics |
|---|---|---|
| Both names in one entry (normal) | One pair = one entry. Write the name like Smith / Jones; with
name_sep set to "/" the name breaks the line after the separator | Per pair |
| Teams with a schedule and automatic orders | One pair = one team. Register the two players as members of the team | Per pair and per player |
Settings for the second way:
- Set
team_gamesof the tournament to 1 (team battle). - Give the format setting (
{ttype}_setting)limit3 (schedule), aschedulewith a single game whosenum_partis 2,setOrder1 (use team orders) andautoOrder1 (fill the orders automatically).autoOrderonly works whensetOrderis 1. - Register the two players of each entry (team) with
/api/v1/team/player/update. Theirindex(1, 2) becomes the initial throwing order (registration order when there is no index). Naming the entrySmith / Jonesas in the first way keeps the brackets easy to read.
{
"team_games": 1,
"name_sep": "/",
"t_setting": {
"tournament": 1, "t_player_count": 16,
"limit": 3, "setOrder": 1, "autoOrder": 1, "exitResult": 1,
"schedule": [
{"subTitle": "Doubles", "startScore": 501, "match_type": "01", "roundLimit": 1, "maxRound": 15, "overkill": 0,
"limit_leg_count": 2, "drawMode": 0, "num_part": 2, "group": 0, "pt": 0, "ignore_avg": 0}
]
}
}
(The other fields of t_setting are omitted. {ttype}_setting is replaced as a whole, so send every field it needs.)
- No orders need to be registered. When a game starts and the order is not set, the server fills it with the first two members of the team in
indexorder. The participants are not asked to submit orders either. An order registered with/api/v1/team/order/updateis used as it is. - The throwing order can be changed on the n01 Live game screen. Before each leg starts, tapping the team name (the player names) in the header swaps the throwing order of that leg, and the next legs keep it. The n01 Live header shows the two players instead of the team name and highlights the one to throw next. The game screen of online matches (n01 Online) has no way to swap them.
- Statistics per player are returned by
/api/v1/tournament/statswithkind=player_stats_list. - A fixture whose schedule has a single game is shown and counted by legs (2-1 etc.), not by games (1-0), in the brackets and standings.
5. Authentication
The API uses HTTP Basic authentication. The user and the password are issued automatically when you subscribe to the API (see Subscribing to the API).
Authorization: Basic <Base64 of user:pass>
On authentication failure the API returns HTTP 401 with result: -40.
Every API user has an admin_id (an n01 administrator id). You can create, update and delete
only the tournaments and leagues that are administered by that id, and the data below them.
Otherwise the API returns HTTP 403 with result: -41.
The APIs that use Basic authentication (creating, updating and deleting data, and authenticated
retrieval) require an API subscription. Without a subscription, or once it has expired, the
API returns HTTP 402 with result: -42. The retrieval APIs without authentication
(public data) can be used without a subscription (so can the password change /api/v1/user/password).
What an API user can do depends on its admin_id:
| admin_id | What it can do |
|---|---|
| Set | Read (including the administration items), create, update and delete the tournaments and leagues of that administrator (a subscription is required) |
| Not set | Retrieval APIs only (public data) |
Subscribing to the API
You subscribe from the payment page of a tournament.
- Open the administration screen (Setting) of a tournament.
- Follow the "About pricing." link to the payment page.
- Select the "API" tab and buy the monthly or the yearly plan with PayPal.
You can subscribe the same way from a league ("About pricing." → "API" tab). Either way there is one subscription per n01 administrator id, not one per competition. It is separate from the subscription that raises the number of players and from the pay per event payment, and the API plans do not raise the number of players of a competition.
One API user is issued automatically per administrator when you subscribe, and the user name and the expiry date are shown on the same "API" tab. The password is shown only once right after it is issued, so keep a copy of it. If you lose it, you can issue a new one with "Reissue password" on the same page (the previous password stops working).
You cancel from the "Subscription list page" on the payment page. Even if you cancel, you can continue to use the API until the expiry date, after which it stops working.
OAuth 2.1 (for MCP clients)
For MCP clients that only offer OAuth or no authentication, such as the custom connectors of claude.ai,
the API server is also an OAuth 2.1 authorization server. It supports the standard flow from client
registration to token issuance (dynamic client registration, authorization code with PKCE, refresh tokens),
so an MCP client discovers it automatically once you register https://push.n01darts.com/api/v1/mcp.
- During the authorization the n01 login page opens. Log in with the Google / Facebook / X account you use to administer your competitions and allow the access; the client then uses the API as that administrator (the same rights as an API user of that administrator).
- If the administrator has no API user yet, one is issued automatically when you allow the access.
The subscription is handled exactly like Basic authentication: without it every authenticated call (reads included) returns
result: -42(the consent page shows whether you have a subscription and where to subscribe). - The access token can be used with the REST API as well, as
Authorization: Bearer <token>. It is valid for 24 hours and is renewed with the refresh token (90 days). An invalid token gets HTTP 401 withWWW-Authenticate: Bearer.
| Endpoint | Description |
|---|---|
GET /.well-known/oauth-authorization-server | Authorization server metadata (RFC 8414) |
GET /.well-known/oauth-protected-resource/api/v1/mcp | Protected resource metadata (RFC 9728) |
POST /api/v1/oauth/register | Client registration (RFC 7591). redirect_uris must be https (http only for localhost) |
GET /api/v1/oauth/authorize | Authorization (response_type=code, PKCE S256 is required) |
POST /api/v1/oauth/token | Token issuance (authorization_code / refresh_token) |
POST /api/v1/oauth/revoke | Token revocation (RFC 7009) |
POST/api/v1/user/password
Changes your own password. Authenticate with the current password, then send the current and the new password as JSON. The new password must be 8 to 100 characters and different from the current one.
{"password": "current password", "new_password": "new password"}
There is a page for it as well:
Change password. Control characters are not allowed in the new password (result: -3).
6. Create / update / delete APIs (Basic authentication)
POST a JSON body (Content-Type: application/json).
All public fields returned by the retrieval APIs can be updated, including nested structures
(brackets, settings, etc.). Non-public items, IDs, the delete flag and
createTime / updateTime cannot be updated.
If the request contains even one field that cannot be updated, or an invalid value, the whole
request is rejected with result: -3 and nothing is updated.
updateTime is updated automatically. Tournament updates also
trigger an update notification so that spectator pages refresh in real time (when the tournament
belongs to a league, the league's updateTime is updated as well).
POST/api/v1/tournament/create
Creates a tournament and returns the newly assigned tdid together with url,
the page participants and spectators open. Show url to the user; it is the address to share.
set accepts the same fields as /api/v1/tournament/update (omitted items
get their default value), and entry_list registers the entries at the same time.
title (tournament name) and join_pass (join password) are required; a request
without them or with an empty value is refused with result: -3. On creation the title is trimmed and,
when it is longer than 60 characters, stored cut to 60 characters followed by ... (the same rule as the administration
screen; tournament/update accepts the full 200 characters).
{
"set": {
"title": "Autumn Open",
"status": 20,
"t_date": 1800000000,
"join_pass": "pass1234",
"rr_setting": {"round_robin": 1, "robin_count": 1, "robin_player_count": 8}
},
"entry_list": [
{"name": "Player One", "c": "JP", "index": 1},
{"name": "Player Two", "c": "JP", "index": 2}
]
}
{"result":0, "tdid":"t_Ab1c_2345", "added":[{"tpid":"Xy3f", "name":"Player One"}, ...],
"url":"https://n01darts.com/n01/tournament/comp.php?id=t_Ab1c_2345"}
| Required | title join_pass |
|---|---|
| Main defaults | status=10 (preparing) kind=darts
ad=1 chat=1 show_avg=1
auto_complete=1 game_type=1 private=0
scorer_pass="" |
| Set by the server | tdid admin_id admin_name
createTime updateTime s_date
pass_hash scorer_pass_hash max_user |
admin_name (the organizer name shown on the pages) is copied from the most recent tournament or
league of the same administrator; when there is none, the API user name is used. Change it afterwards with
tournament/update if needed.
Administrators the site operator has exempted from payment get the tournament without max_user
(no player limit), and administrators exempted from advertisements get ad 0, exactly as in the
administration screen.
Creating with status 30 (in progress) is subject to the player limit described under
/api/v1/tournament/update; when it is exceeded the created data is removed again and result: -5 is returned
(result: -6 when the limit could not be checked).
A tournament cannot be created with status 30 while the bracket of an enabled format is empty (result: -3).
The format exclusions (league and round robin, double and single elimination cannot be enabled together) and the automatic
third place table are the same as for /api/v1/tournament/update.
With lgid the tournament is created as an event of that league (you must administer the
league). The administrator information is inherited from the league and league becomes 1.
An event of a league opens on the league area's page, so url becomes
https://n01darts.com/n01/league/season.php?id=<tdid>.
Only the enabled ones of lg_setting / rr_setting / t_setting /
s2_setting / d_setting / m_setting are stored, together with
their empty brackets.
The response also carries the updateTime of the created document, so that it can be passed as
expect_update_time to a following tournament/update (league/create behaves the same).
POST/api/v1/tournament/update
Updates a tournament. All public fields returned by /api/v1/tournament/get can be
specified, including the bracket (table) and the various settings.
tdid and entry_list cannot be updated (use
/api/v1/tournament/entry/update for entries).
The administrator information (admin_id), max_user, the delete flag and the items only the
site operator can change (ranking and special progression options) cannot be updated either. An empty set is
refused with result: -3. The advertisement flag (ad) is decided by the payment state,
so it cannot be given on creation nor on update.
Setting status to 30 (in progress) is subject to the same player limit as the administration
screen: when the entries of the tournament (together with the organizer's other tournaments in progress)
exceed the free players plus the purchased players, the request is refused with result: -5
(HTTP 402) and nothing is written (the check is skipped when the tournament is already in progress, or when it has no player
limit because the organizer is exempt from payment; result: -6 when the payment server could not be reached).
The organizer can buy players or a subscription on the pricing page of the
administration screen. Other status changes are not affected.
To move the tournament into another league by changing lgid, you must administer that league.
When join_pass / scorer_pass are updated, the server recalculates the
pass_hash / scorer_pass_hash used to check them.
title and join_pass are required items, so an update that empties them is
refused with result: -3.
An update through this API invalidates the administration screens that are open for the tournament, just
like saving it from another screen does: their next save fails with "The data has been updated" and the
screen has to be reloaded.
Conversely, to avoid overwriting a change made from the administration screen (or by another API client)
between your read and your update, send the updateTime returned by
/api/v1/tournament/get as expect_update_time (UNIX milliseconds).
When the tournament has been updated since, the request is refused with result: -7 (HTTP 409)
and nothing is written; read the tournament again and retry (a non-integer expect_update_time is refused with
result: -51).
{
"tdid": "tournament ID",
"expect_update_time": 1767225600000,
"set": {
"title": "Spring Open 2026",
"status": 30,
"theme": "dark"
}
}
The values of the following fields are validated.
| Field | Value |
|---|---|
title | String (up to 200 characters, cannot be empty) |
details | String (up to 10000 characters) |
t_date s_date | Competition date / sort date (integer, UNIX time in seconds, 0 when not set). Changing t_date does not update s_date |
lg_setting.swiss swiss_bh swiss_rounds | Swiss system settings. swiss / swiss_bh are 0 / 1, swiss_rounds an integer 0-1023 (the rest of the settings is not validated) |
status | 10=preparing / 20=accepting entries / 25=building the bracket / 30=in progress / 40=finished (other values are rejected).
An update to 30 is refused with -3 when the bracket of an enabled format (lg_table / rr_table / t_table /
s2_table / dw_table / m_table) is missing or empty (the same as "the bracket has not been created" on the
administration screen; a bracket sent in the same request counts). A tournament already at 30 is not checked |
private | 0 / 1 (hide from the public list) |
entry_lock | 0 / 1 (lock entries) |
order_empty_error | 0 / 1 |
color | Background color as a CSS color value (#rrggbb, #rgb, a color name such as white, or rgb() / rgba() / hsl() / hsla(); up to 50 characters, "" to clear) |
image | String (image URL, up to 2000 characters) |
theme | "" / dark / scifi / neon / orange / custom |
theme_css | URL of a custom theme CSS (must start with https:// or /) |
lang | Display language (""=automatic, or a language code in /n01/lang/ such as ja or en) |
kind | Kind of competition (up to 30 characters), e.g. darts softdarts billiards |
lgid | ID of the league it belongs to (up to 100 characters) |
game_type | Integer (bit flags, 0-7). 1=n01 Live / 2=n01 Online / 4=submit results |
league softdarts chat show_avg
auto_complete confirm_start dynamic_avg lf
individual_pass hide_sns common_join
show_entry_no team_games select_first
win_lose | 0 / 1 |
sd_legs | Integer (0-99) |
name_sep | String (up to 10 characters) |
admin_name | Organizer name (up to 200 characters) |
join_pass scorer_pass | Join password / scorer password (up to 100 characters; join_pass cannot be empty) |
lg_setting rr_setting t_setting
s2_setting d_setting m_setting |
When the block is enabled (league / round_robin / tournament / matchs is 1) its size is validated:
robin_count (1 or more) and robin_player_count (2 or more) with a product of at most 1024,
t_player_count (a power of two from 2 to 1024; 4 or more for d_setting),
match_count (1 to 512).
The league format (lg_setting.league) and round robin (rr_setting.round_robin), and double elimination
(d_setting.tournament) and single elimination (t_setting.tournament / s2_setting.tournament)
cannot be enabled at the same time (the same exclusion as the administration screen; the stored settings are taken into account, so
send the setting you disable in the same request when switching).
When t_setting.t3 / s2_setting.t3 is 1 and t3_table / s2_3_table is missing or empty,
the server creates the empty third place table ([["",""],[""]]).
The game id schid of each row of schedule (and of the schedule inside each game_setting element)
is assigned by the server when missing or empty (4 characters of 0-9a-z; existing values are kept). A duplicate within one schedule,
or a value that is not a string, is -3 |
t_table t3_table s2_table s2_3_table
dw_table dl_table m_table rr_table lg_table |
Must be arrays |
t_result t3_result s2_result s2_3_result
dw_result dl_result m_result rr_result lg_result
rr_rank lg_rank |
Must be objects or arrays |
| Other fields | Keys must not contain $ or . and must not be JavaScript reserved names (__proto__, constructor, ...);
nesting is limited to 64 levels. Any violation rejects the whole request with -3 |
Settings and brackets: what to take care of (things that affect the progress of the tournament)
The administration screen prevents the following inconsistencies in its UI; the API does not check them. Getting them wrong shows up as matches that cannot be started or finished, or as a tournament that never completes.
{ttype}_settingis replaced as a whole. Sending only{"tournament":1,"t_player_count":16}drops the storedlimit/limit_leg_count/limit_set_count/schedule/game_setting/drawModeand so on. Without a leg count the matches never finish, andlimit3 (schedule) withoutschedulemakes the result registration fail with a server error. Read the whole setting with the retrieval API, change it and send it back. An enabled setting needs at leastlimit(0=no limit / 1=legs / 2=sets / 3=schedule) with the matchinglimit_leg_count/limit_set_countandlimit_set_leg_count/schedule(an array), anddrawMode(0 / 1; 0 when the leg count is 1). The league format and round robin also need the pointspoint_w/point_d/point_l(win / draw / loss); without them the standings cannot compute the points.low_win(lower score wins) only has a meaning withlimit0.- Each row of
schedule(limit3, schedule mode / team matches) defines one game. A row hassubTitle(label),startScore(start score of 01; 0 lets the players choose),match_type("01"or"cricket"; 01 when omitted),limit_leg_count(legs of that game),drawMode,roundLimit/maxRound(round limit on/off and count),overkill,num_part(players per team in that game; 1=singles / 2=doubles),group/pt/ignore_avg(grouping, points and average exclusion for the statistics) andschid(game id).schidcan be omitted because the server assigns it, but never change theschidof an existing game (orders and match data are tied to it; a changed id is a different game). The safe way is to reuse the rows read with the retrieval API. For team matches the format setting also takessetOrder(1: use team orders) andautoOrder(1: fill the orders automatically) (4.10 Doubles). - Write results with
/api/v1/tournament/result/update. Writing{ttype}_resultdirectly withtournament/updateis not refused, but then none of the progression happens: no winner is moved to the next round, no loser to the Losers bracket, no completion check, no badge update (the result is displayed but the tournament does not advance). Use the direct write only for correctionsresult/updatecannot do (removing a wrong result, for example). - Do not set
game_typeto 0. The bit flags of the participation methods (1=n01 Live / 2=n01 Online / 4=submit results) at 0 leave the participant pages without any way to start a match. Use a value from 1 to 7 (the administration screen can save 0 too, so check existing tournaments as well). - Give the entries of an event under a league their
lpid(league entry id). The league statistics (standings, stats) identify a league player through thelpidof the entries of each event. An entry added with/api/v1/tournament/entry/updatewithoutlpidis left out of the league statistics for that event, and a wronglpidcredits another player. Use thelpidfrom/api/v1/league/entry/list(the progress of the tournament itself is not affected). - The
roundvalues ofgame_setting(per-round overrides). Single elimination: 1 and above is that round, -1=final, -2=semi-final, -3=third place match. Double elimination: 1 and above is that Winners round, -1=grand final reset, -2=grand final, -3=Winners final, -4=Winners semi-final, -5=Losers final, -6=Losers semi-final, -11 and below is that Losers round (-11=round 1, -12=round 2, ...). Round robin / league format: the block (division) number starting at 0. A wrong round applies its leg count to other matches. - Byes have to be advanced to the next round by you.
A first round slot with a player on one side only is advanced automatically by the administration screen when the bracket page is opened;
nothing does this when the bracket is written through the API. Put the
tpidinto the matching slot oft_table[1](round 2) and, when empty slots chain, further up. Otherwise the player does not appear in round 2 until an administrator opens the bracket page. - The league format does not accept results without match cards.
Matches of the league format are played per match card (fixture; what
/api/v1/league/schedule/getreturns), which is stored separately fromlg_table(the players of each division). Settinglg_setting.leagueto 1 and fillinglg_tabledoes not create the cards (the administration screen creates them when the bracket page is opened; the API does not). Create them for every division that has players with/api/v1/league/schedule/generate(orupdate) before the tournament goes in progress. An update tostatus30 only checks that the bracket (lg_table) exists; it is not refused when the cards are missing. In a division without cards the participant pages show the division and the names only, without a button to start a match, results are refused and the tournament never completes. Creating the cards while the tournament is in progress (generateorupdate) recovers from that state (no data is damaged). The safe way is to confirm with/api/v1/league/schedule/getthat every division with players has cards before going to 30. When you changerobin_count, adjust the number of divisions of the cards too (arobin_countabove the number of divisions is a server error). The results of Swiss byes are recorded by the server when the cards are saved and whenstatusbecomes 30 (as on the administration screen). - Removing an entry does not remove it from the brackets.
removeof/api/v1/tournament/entry/updatedoes not look at thetpidleft in{ttype}_table. Atpidthat does not exist shows as an empty slot and nobody can start that match. Remove it from the tables too. - When you replace
rr_table, adjust the related fields. The administration screen always savesrr_tabletogether withrr_seq(match order; each pair sorted bytpid) /rr_order/rr_board/rr_disable. Changingrr_tablealone leaves them pointing at the old placement and the match order and progress counts go wrong. Rebuild them from the newrr_tableor clear them with the table. - Keep the player count of
assign_setting(assignment to the final bracket) within the bracket size. A total of advancing players above thet_player_countof the final bracket is not refused; the surplus players are silently dropped on assignment. - Send
s_datewith the same value when you changet_date(the date used for sorting the lists does not follow automatically).
Give the brackets of an enabled format the same shape the administration screen creates: t_table / s2_table have
log2(t_player_count) + 1 rows whose length halves each round, dw_table has log2(t_player_count) + 3 rows,
dl_table has 2 × (log2(t_player_count) − 1) rows, m_table has match_count rows of [left, right],
rr_table / lg_table have robin_count rows of robin_player_count slots.
A different shape shows up as winners that are not written into the next round, Losers players that disappear, or a tournament that never
completes (the API does not check the shape).
lgid or private also updates lgid / private of the matches of the tournament
(live and archived), like linking a season on the management screen.
POST/api/v1/tournament/delete
Deletes a tournament (a soft delete that sets the delete flag and removes the link to its league). After that it is no longer visible from the retrieval APIs.
{"tdid": "tournament ID"}
POST/api/v1/tournament/entry/update
Adds, updates, and removes tournament entries. add / update /
remove are all optional; specify only what you need (result: -51 when all three are empty).
remove deletes the entries for good (unlike the remove of team players it cannot be undone;
the state before the change is kept in the backup).
{
"tdid": "tournament ID",
"add": [
{"name": "New Player", "c": "JP", "index": 10}
],
"update": [
{"tpid": "aaaa", "name": "Renamed Player", "join": 1}
],
"remove": ["bbbb"]
}
All public entry fields can be specified (tdid, tpid, and SNS-related
identification cannot be updated). The values of the following fields are validated.
| Field | Value |
|---|---|
name | Display name (leading/trailing spaces and control characters are removed; longer than 60 characters is stored cut to 60 characters plus ...; longer than 200 characters is rejected with result: -3). Required when adding |
c | Country code (up to 10 characters) |
sname | Sub name (up to 100 characters; not returned by the retrieval APIs) |
join | Integer (0-9). Participation state |
index | Integer (0-100000). Sort order |
startScore | Integer (0-100000). Handicap |
pass | Individual password (string, up to 100 characters). Stored with the same rule as the join page (trimmed and lower-cased before hashing); the password itself is not stored. "" clears it (same as "clear password" on the management screen) |
release_sns | 1 releases the SNS link of the entry (same as "release SNS" on the management screen; sns_id, sns_type and the SNS-derived sname are kept aside so that the link can be restored) |
Added entries get a newly assigned tpid, returned in the response's added.
update targets an entry by its tpid. The response's updated /
removed are the numbers of entries actually processed.
{"result":0, "added":[{"tpid":"Xy3f", "name":"New Player"}], "updated":1, "removed":1}
POST/api/v1/league/create
Creates a league and returns the newly assigned lgid together with url,
the league portal page.
set accepts the same fields as /api/v1/league/update, and
entry_list registers the entries at the same time.
title (league name) is required; a request without it or with an empty value is refused
with result: -3.
{
"set": {"title": "Winter League", "details": "season 3"},
"entry_list": [{"name": "League Player", "c": "JP"}]
}
{"result":0, "lgid":"lg_Ab1c_2345", "added":[{"lpid":"Xy3f", "name":"League Player"}],
"url":"https://n01darts.com/n01/league/portal.php?lgid=lg_Ab1c_2345"}
| Required | title |
|---|---|
| Main defaults | ad=1 private=0
sort=date sort_order=-1 |
| Set by the server | lgid admin_id admin_name
createTime updateTime |
admin_name is copied from the most recent tournament or league of the same administrator;
when there is none, the API user name is used.
POST/api/v1/league/update
Updates a league. All public fields returned by /api/v1/league/get can be specified
(lgid, entry_list, createTime, updateTime, the administrator information
(admin_id), the advertisement flag (ad) and the items only the site operator can change cannot be updated).
title is a required item, so an update that empties it is refused with result: -3.
Like /api/v1/tournament/update, the update invalidates the open administration screens of the
league, and expect_update_time (the updateTime returned by
/api/v1/league/get) refuses the update with result: -7 when the league has been
updated in between.
{
"lgid": "league ID",
"expect_update_time": 1767225600000,
"set": {"title": "Main League 2026"}
}
The values of the following fields are validated.
| Field | Value |
|---|---|
title | String (up to 200 characters, cannot be empty) |
details | String (up to 10000 characters) |
show_details | 0 / 1 (show the description on the portal) |
image | String (image URL, up to 2000 characters) |
color | Background color as a CSS color value (same as a tournament) |
private | 0 / 1 (hide from the public list) |
show_count | Integer (0-10000, number of events per page; 0 means the default 10) |
status | Integer (0-99) |
theme | "" / dark / scifi / neon / orange / custom |
theme_css | URL of a custom theme CSS (must start with https:// or /) |
lang | Default display language for new events (""=automatic) |
sort | Order of the events (date / name / manual) |
sort_order | 1 (ascending) / -1 (descending) |
admin_name | Organizer name (up to 200 characters) |
join_pass scorer_pass | Join password / scorer password (up to 100 characters) |
POST/api/v1/league/entry/update
Adds, updates, and removes league entries. add / update /
remove are all optional. It works like the tournament entry update, but entries are
addressed by lpid.
{
"lgid": "league ID",
"add": [{"name": "New Player", "c": "JP"}],
"update": [{"lpid": "aaaa", "name": "Renamed Player"}],
"remove": ["bbbb"]
}
All public entry fields can be specified (lgid, lpid, and SNS-related
identification cannot be updated). The validated fields are name (required when
adding), c, sname and index.
{"result":0, "added":[{"lpid":"Xy3f", "name":"New Player"}], "updated":1, "removed":1}
POST/api/v1/league/delete
Deletes a league (a soft delete). When the league still has events (tournaments), the request is
rejected with result: -3; delete those events or unlink them from the league first.
{"lgid": "league ID"}
POST/api/v1/match/create
Creates the match data (the per-leg scores) of a finished match, e.g. to import matches scored
outside n01 or old records. The match is stored in the archive (shown in the history and counted in
the statistics) and can be read with /api/v1/match/get / /api/v1/match/list.
Only the administrator of the tournament (tdid) can create matches.
set takes the fields that /api/v1/match/get returns.
statsData (2 players, each with the tpid of an entry) and
legData (the array of legs, same structure as the retrieval API) are required;
ttype / round / t_no (the position in the bracket; tmid is derived from
ttype, round and the two tpid when omitted),
startTime (UNIX seconds, default now), match_type (01 / cricket),
startScore, limitLeg / limitSet,
scid / currentSet (in the set format one set is one match document, grouped by the same scid)
and title are optional.
In statsData, name defaults to the entry name and winLegs / allScore / allDarts
are computed from legData (01) when omitted (the SNS link fields are left empty).
{
"tdid": "tournament ID",
"set": {
"ttype": "rr", "round": 0, "startTime": 1105335600,
"startScore": 501, "limitLeg": 2,
"statsData": [{"tpid": "aaaa"}, {"tpid": "bbbb"}],
"legData": [
{"first": 0, "winner": 1, "currentRound": 5, "currentPlayer": 1, "endFlag": 1,
"playerData": [
[{"score": 0, "left": 501}, {"score": 100, "left": 401}, {"score": 60, "left": 341}, {"score": 85, "left": 256}, {"score": 100, "left": 156}, {"score": 60, "left": 96}],
[{"score": 0, "left": 501}, {"score": 140, "left": 361}, {"score": 100, "left": 261}, {"score": 81, "left": 180}, {"score": 140, "left": 40}, {"score": 60, "left": -20}, {"score": -2, "left": 0}]
]}
]
}
}
{"result":0, "mid":"Ab3kR9xz_1700000000000", "tmid":"t_xxxx_rr_0_aaaa_bbbb", "startTime":1105335600, "updateTime":1700000000000}
*_result) is not written; use /api/v1/tournament/result/update
to enter the result together with the match data.
Creating a match updates the updateTime of the tournament and sends the update notification
(the statistics cache is rebuilt).
mid, the delete flag, internal fields and tdid / lgid cannot be given in set (result: -3).
POST/api/v1/match/update
Updates a match. The archive copy is the primary target; when the match also exists among the
matches in progress, both are updated at the same time to keep them in sync. All public fields
returned by /api/v1/match/get can be specified, including statsData
(mid, the delete flag, internal fields and the identification of the tournament and bracket the match
belongs to (tdid lgid tmid schid scid ttype round gs_round)
cannot be updated). When statsData is updated,
the items that the retrieval API masks keep their server-side values.
Only the administrator of the tournament the match belongs to (tdid) can update it
(a match without a tdid cannot be updated).
{
"mid": "match ID",
"set": {"title": "Grand Final", "private": 1}
}
The values of the following fields are validated.
| Field | Value |
|---|---|
title | String (up to 200 characters) |
private | 0 / 1 (hide from the history list) |
updateTime of the tournament it belongs to and sends the update notification
(the statistics cache is rebuilt).
POST/api/v1/match/delete
Deletes a match (a soft delete that sets the delete flag). When the match exists both in the archive
and among the matches in progress, both are flagged. As with the update, only the administrator of
the tournament the match belongs to (tdid) can do this (a match without a
tdid cannot be deleted).
{"mid": "match ID"}
updateTime and sends an update notification,
but the bracket results (*_result) and the team order results are not recalculated.
Update the bracket with /api/v1/tournament/update when you need to.
POST/api/v1/team/player/update
Adds, updates, and removes the members of a team (tpid).
add / update / remove are all optional; specify only what you
need.
{
"tdid": "tournament ID",
"add": [{"tpid": "aaaa", "oname": "Team Member", "opid": "P-01", "index": 1}],
"update": [{"tpid": "aaaa", "oid": "Xy3f", "oname": "Renamed Member"}],
"remove": [{"tpid": "aaaa", "oid": "Ab1c"}]
}
The values of the following fields are validated.
| Field | Value |
|---|---|
oname | Player name (control characters are removed; up to 60 characters, longer values are rejected with result: -3). Required when adding |
opid | Player number or similar (up to 20 characters) |
index | Integer. Sort order |
delete | 0 / 1 (deleted state) |
add requires tpid and oname, update / remove require tpid
and oid (otherwise result: -3; result: -51 when all three are empty).
Added members get a newly assigned oid, returned in the response's added
(lgid is inherited from the tournament). update and remove
address a member by tpid and oid.
{"result":0, "added":[{"tpid":"aaaa", "oid":"Xy3f", "oname":"Team Member"}], "updated":1, "removed":1}
remove is a soft delete that sets the delete flag (names already used in an order are
still displayed). Send "delete": 0 with update to restore a member.
Deleted members can be listed with /api/v1/team/player/list?...&all=1
(administrators of that tournament only).
POST/api/v1/team/order/update
Registers, updates and removes team orders. update stores the order for a
(tmid, tpid, schid) combination and adds it when it does not
exist yet (the number of added orders is returned in added).
{
"tdid": "tournament ID",
"update": [
{"tmid": "...", "tpid": "aaaa", "schid": "...", "order": [{"oid": "Xy3f"}, {"oid": "Ab1c"}]}
],
"remove": [{"tmid": "...", "tpid": "aaaa", "schid": "..."}]
}
{"result":0, "added":1, "updated":0, "removed":1}
| Field | Value |
|---|---|
order | Array of the order (up to 200 items). Each item has oid and optionally modify (0 / 1) |
statsData order of the matching game with the
player names filled in, and an update notification for the order pages is sent.
remove deletes the order and empties the order on the match side.
The order result (res) cannot be updated, because it implies recalculating the bracket;
update results with /api/v1/tournament/update.
POST/api/v1/tournament/result/update
Enters (or clears) the result of one match with the same processing as the result input of the management screen.
The server writes both sides of <ttype>_result, advances the winner to the next round (and the loser of a double
elimination to the losers bracket), fills the third place match and finishes the tournament (status 40) when auto_complete
is on and every match is over. Writing *_result directly with /api/v1/tournament/update does none of this,
so use this API to enter results.
{
"tdid": "tournament ID",
"ttype": "t",
"round": 0,
"t_no": 1,
"tpid": "aaaa",
"vsTpid": "bbbb",
"result": 3,
"vsResult": 1,
"detail": {"a": 65.2, "t": 4, "t4": 1, "t8": 0, "h": 80, "b": 15},
"vsDetail": {"a": 58.0}
}
| Field | Value |
|---|---|
ttype | t t3 s2 s2_3 rr lg dw dl m |
round | Round index (first round = 0). Block index for rr, match index for m, the string "<division>_<lsid>" for lg |
t_no | Match number in the round (1-based) for t t3 s2 s2_3 dw dl; 0 otherwise |
tpid vsTpid | The two players (teams). For a bye of a normal league pass "empty" as vsTpid |
result vsResult | Legs won by each side (sets in a set format, games won in a team event). Pass both as null to clear the result |
detail vsDetail | Optional statistics (a average, t 100+, t4 140+, t7 170+, t8 180, h high out, b best leg, a_b / w_b legs played and won as second thrower, mk cricket mark distribution, add bonus points, g legs per game of a team event, l legs of a set format). An unknown key or a value that is not a number / array of numbers is refused with result: -51 |
tpid and vsTpid must differ, and result / vsResult must both be numbers or both null.
Invalid parameters (ttype, round, t_no, ...) are refused with result: -51; when the
management backend does not accept the request, result: -3 is returned.
result: -62 is returned.
POST/api/v1/league/schedule/update
Replaces the fixtures (match cards) of one division of the league format as a whole, with the same processing as saving the cards on the
management screen. The results of swiss byes (p is [tpid, "empty"]) are recorded by the server.
{
"tdid": "tournament ID",
"div": 0,
"schedule": [
{"p": ["aaaa", "bbbb"], "lsid": "ab3f", "t": ""},
{"p": ["cccc", "dddd"]}
],
"expect": 2
}
| Field | Value |
|---|---|
div | Required. Division index (0-1024) |
schedule | Every card of the division (at most 4096). Each item has p (required; two tpid, "" empty slot / "empty" bye), lsid (4 lower-case letters / digits; keep the value of existing cards and never repeat one: a card with a new lsid is a different card and loses its result; omit it for new cards), t (title, cut at 100 characters), r (swiss round number, 1-1024) |
expect | Optional. The current number of cards the change is based on. When it differs from the server, the update is refused with result: -7 and nothing is written (protection against concurrent changes from another device) |
The response carries the stored schedule including the assigned lsid, and div.
Both update and generate require the league format (lg_setting.league = 1) and refuse anything else with result: -51.
POST/api/v1/league/schedule/generate
Generates the fixtures from lg_table (the players of each division) and saves them, with the same rules as the automatic
pairing and the swiss buttons of the management screen. Without div every division is processed.
swiss_* on a normal league, robin on a swiss league, and a missing robin_count are refused with result: -51.
{"tdid": "tournament ID", "div": 0, "mode": "auto"}
mode | Action |
|---|---|
robin | Round robin (normal league): every pairing (twice with turnaround); cards that already have a result keep their lsid |
swiss_first | Creates the empty slots of round 1 of a swiss league (⌈players / 2⌉ rows) |
swiss_assign | Fills the empty slots with the unassigned players at random (one bye when the count is odd) |
swiss_next | Generates the next round (paired by rank within the point groups, avoiding rematches and repeated floats; rematch counts the unavoidable rematches) |
auto (default) | robin for a normal league. For a swiss league: round 1 with random assignment when there is no round yet, the assignment when slots are empty, else the next round |
{"result":0, "swiss":1, "divisions":[
{"div":0, "before":3, "action":"swiss_next", "round":2, "total":3, "blank":0, "rematch":0, "after":6, "schedule":[...]}
]}
Divisions that were not processed carry the reason in skipped (not enough players, every round created, empty slots left, ...).
Each division is saved with its current card count as expect, so a concurrent change on another device gives result: -7.
POST/api/v1/league/tournament/link
Makes a tournament an event of a league (same as linking a season on the management screen). lgid and tdid are
required and you must administer both. lgid and the private flag of the league are set on the tournament and its matches.
{"lgid": "league ID", "tdid": "tournament ID"}
POST/api/v1/league/tournament/unlink
Detaches an event from its league (same as unlinking on the management screen). lgid is removed from the tournament,
its entries, its team members and its matches. lgid and tdid are required and you must administer both;
when the tournament does not belong to that league the request is refused with result: -51.
{"lgid": "league ID", "tdid": "tournament ID"}
POST/api/v1/team/order/fix
Fixes (fix 1) or releases (fix 0) the order of a team, as the administrator does on the order page.
Once both teams have fixed, each can see the order of the other.
{"tdid": "tournament ID", "tmid": "match card ID", "tpid": "aaaa", "vsTpid": "bbbb", "fix": 1}
POST/api/v1/team/order/result
Enters the result of one game (schid) of a team match card by hand (same as the result input of the card on the management
screen). The server counts the games won, writes the card result into <ttype>_result and advances the bracket.
{
"tdid": "tournament ID",
"tmid": "match card ID",
"schid": "a1b2",
"ttype": "t",
"round": 0,
"t_no": 1,
"tpid": "aaaa",
"vsTpid": "bbbb",
"p1res": {"r": 3, "a": 70.5},
"p2res": {"r": 1, "a": 61.0}
}
| Field | Value |
|---|---|
ttype round t_no | Same as tournament/result/update |
gs_round | Optional. The round used for the round-specific game settings (default: round, the division for lg) |
p1res p2res | Results of tpid / vsTpid. r (legs won) is required; the other keys are the statistics of detail |
POST/api/v1/tournament/badge/update
Sets the badge (board number) of matches, like the badge management of the management screen. Pass one badge in the body or several in
list. Participants see the change immediately through the update notification.
{"tdid": "tournament ID", "ttype": "t", "round": 0, "index": 2, "str": "5", "st": 1}
{"tdid": "tournament ID", "list": [{"ttype": "t", "round": 0, "index": 2, "str": ""}, {"ttype": "rr", "round": 1, "index": 0, "str": "A-3", "st": 2}]}
| Field | Value |
|---|---|
ttype | t t3 s2 s2_3 dw dl m rr lg |
round index | Round index and slot index (the match of slots 2k and 2k+1 is t_no k+1). The badge key is "<ttype>-<round>-<index>" |
str | Board text (up to 40 characters). "" removes the badge |
st | 0 none / 1 in progress (default when str is set) / 2 finished |
t_memo t_memo_tpid | Optional. Also writes the memo of the match (e.g. the referee). A match that already has a memo is left alone, and nothing is written when t_memo_tpid plays in that match (the same rule as the automatic referee) |
list | Several badges in one request (1-200) |
{"result":0, "updated":2}
POST/api/v1/tournament/memo/update
Sets the memo shown under each round robin block (ttype rr) or league division (lg).
memo is an array of strings, one per block / division (at most 1024 items, each cut at 200 characters); an empty array clears them.
{"tdid": "tournament ID", "ttype": "rr", "memo": ["Board 36", "Board 37"]}
POST/api/v1/tournament/t_memo/update
Sets the memo shown at a match of a bracket (up to 40 characters, e.g. the referee). key is
"<ttype>-<round>-<index>" with the even slot index of the match (the same key as a badge);
str "" clears it. Pass one in the body or several (1-200) in list. The response carries updated (the count).
{"tdid": "tournament ID", "key": "t-0-2", "str": "Referee: Taro"}
POST/api/v1/tournament/announce/update
Sets the announcement shown to the participants (up to 200 characters). "" clears it. announceTime
(UNIX milliseconds) defaults to the current time, or to 0 when the announcement is cleared. The response returns the stored
announce / announceTime.
{"tdid": "tournament ID", "announce": "The final starts at 18:00"}
POST/api/v1/tournament/assign/update
Saves how the qualifiers of the round robin / league groups are assigned to the final brackets (assign_setting).
The values are sanitized with the same rules as the assignment settings of the management screen and the stored
assign_setting is returned. assign replaces the stored settings as a whole (it is not a partial
update): omitted items get their defaults (t_type=top / s2_type=low /
count=2 / every flag false / referee_type=lowest) and out-of-range values are replaced by the
default instead of being rejected. The current values are in assign_setting of tournament/get.
{"tdid": "tournament ID", "assign": {"t_type": "top", "t_count": 2, "t_complete": true, "s2_type": "low", "s2_count": 2}}
Field (prefixed with t_ / s2_) | Value |
|---|---|
type | top / low / custom (per group size) |
count | Players taken from each group (1-99) |
placeholder complete referee | true / false. Show rank placeholders in undecided slots / assign finished groups only / set referees |
referee_type | lowest / random |
custom | {"<group size>": {"type": "top", "count": 2}} |
POST/api/v1/tournament/copy
Copies a tournament (same as the copy of the management screen: status 10, same settings, same league) and returns the new
tdid and url.
{"tdid": "tournament ID", "title": "Autumn Open 2027", "date": 0, "entry": 1, "result": 0}
| Field | Value |
|---|---|
title | Optional. Title of the copy, up to 60 characters (default: the same title) |
date | 1 keeps the date (default 0) |
entry | 1 copies the entries and the tables (default 0; the badges, match order and match memos are copied with them) |
result | 1 also copies the results (needs entry 1; default 0) |
guide | 1 also copies the guide (the initial bracket {ttype}_init; default 0) |
{"result":0, "tdid":"t_Ab1c_2345", "url":"https://n01darts.com/n01/tournament/comp.php?id=t_Ab1c_2345"}
POST/api/v1/tournament/match/release
Releases the game lock (same as "Release game lock" in the match menu of the management screen).
When n01 Live refuses to start a match card (tmid, optionally one game schid of a team event) because
the players are "locked, playing elsewhere", this clears the in-game state of both players so that they can start again.
The match data, the bracket and the results are not touched.
{"tdid": "tournament ID", "tmid": "match card ID"}
POST/api/v1/autopilot/update
Updates the autopilot settings. Only the fields given in config replace the stored ones (types is merged per type),
the values are sanitized with the same rules as the settings page and the autopilot server is notified immediately.
The stored settings are returned.
{"tdid": "tournament ID", "config": {"types": {"t": {"badge_number": "1-10,12", "break_time": 5, "round": 2.5, "enable": 1}}, "remove_old_badge": 1}}
| Field | Value |
|---|---|
types.<t|s2|dw|dl>.badge_number | Boards to use (e.g. "1-10,12", up to 200 characters) |
types.<t>.break_time | Break after a match (minutes, 0-1440) |
types.<t>.round | Rounds to assign (0-99 in steps of 0.5). 0 every round / x up to round x / .5 adds the third place match (only when x is the round before the final; the final is never included) |
types.<t>.enable | 0 / 1. Run the automatic assignment |
remove_old_badge set_referee | 0 / 1. Remove the badges of finished matches / set referees |
referee_type | same_board / prev_upper / prev_lower / prev_random |
name_control name_mode name_sep name_stop name_regex priority hold_robin | Name extraction and priority (when the same people play several events). name_mode is auto / simple / regex, priority -99 to 99 |
7. Result codes
| result | HTTP | Meaning |
|---|---|---|
| 0 | 200 | Success |
| -1 | 404 | Target not found (does not exist / deleted) |
| -3 | 400 | Invalid update field (not allowed / invalid value) |
| -5 | 402 | The players of the tournament exceed the limit the organizer has paid for; it cannot be set to status 30 (in progress) |
| -6 | 502 | The player limit could not be verified (payment server error); the tournament is not started |
| -7 | 409 | The target has been updated since expect_update_time (expect for fixtures); nothing is written |
| -40 | 401 | Authentication error |
| -41 | 403 | Permission error (not the administrator of the data / no admin_id) |
| -42 | 402 | No API subscription / the subscription has expired |
| -43 | 403 | Access from the client's IP address is denied |
| -50 | 400 / 413 / 415 | Invalid request body (not valid JSON; 413 when the body exceeds 1MB; 415 when Content-Type is not application/json) |
| -51 | 400 | Invalid parameter |
| -52 | 404 | Unknown endpoint |
| -53 | 405 | Method not allowed |
| -54 | 503 | The query took too long (list APIs are cut off after 10 seconds); narrow the filter and retry |
| -55 | 429 | Too many requests in a short time (a per-address limit, about 300 requests per minute). Wait the seconds given in the Retry-After header and retry. MCP requests are refused with the same HTTP 429 |
| -60 | 501 | The statistics API or the management (PHP) backend used by the result / fixture / badge / autopilot APIs is disabled (not configured on the server) |
| -61 | 502 | Statistics server error |
| -62 | 502 | The management backend (PHP) could not be reached or refused the operation (APIs that go through the management screen: results, fixtures, badges, ...) |
| -99 | 500 | Internal server error |
8. Examples (curl)
# Tournaments in progress
curl "https://push.n01darts.com/api/v1/tournament/list?status=30&count=20"
# A single tournament (with entries)
curl "https://push.n01darts.com/api/v1/tournament/get?tdid=XXXX"
# Tournament statistics
curl "https://push.n01darts.com/api/v1/tournament/stats?tdid=XXXX&kind=stats_list"
# Finished matches of a tournament, ordered by start time
curl "https://push.n01darts.com/api/v1/match/list?tdid=XXXX&endMatch=1&sort=startTime&order=asc"
# Team orders
curl "https://push.n01darts.com/api/v1/team/order/list?tdid=XXXX&tmid=YYYY"
# Update a tournament title
curl -u apiuser:apipass -H "Content-Type: application/json" \
-d '{"tdid":"XXXX","set":{"title":"Spring Open 2026"}}' \
"https://push.n01darts.com/api/v1/tournament/update"
# Add an entry
curl -u apiuser:apipass -H "Content-Type: application/json" \
-d '{"tdid":"XXXX","add":[{"name":"New Player","c":"JP"}]}' \
"https://push.n01darts.com/api/v1/tournament/entry/update"
# Tournaments you administer (including the private ones)
curl -u apiuser:apipass "https://push.n01darts.com/api/v1/tournament/list?owner=1"
# Create a tournament (with entries)
curl -u apiuser:apipass -H "Content-Type: application/json" \
-d '{"set":{"title":"Autumn Open","status":20,"join_pass":"pass1234"},
"entry_list":[{"name":"Player One","c":"JP"}]}' \
"https://push.n01darts.com/api/v1/tournament/create"
# Create a league
curl -u apiuser:apipass -H "Content-Type: application/json" \
-d '{"set":{"title":"Winter League"}}' \
"https://push.n01darts.com/api/v1/league/create"
# Delete a tournament
curl -u apiuser:apipass -H "Content-Type: application/json" \
-d '{"tdid":"XXXX"}' \
"https://push.n01darts.com/api/v1/tournament/delete"
# Enter the result of the first match of round 1 (the winner advances)
curl -u apiuser:apipass -H "Content-Type: application/json" \
-d '{"tdid":"XXXX","ttype":"t","round":0,"t_no":1,"tpid":"aaaa","vsTpid":"bbbb","result":3,"vsResult":1}' \
"https://push.n01darts.com/api/v1/tournament/result/update"
# Generate the league fixtures (the next round of a swiss league)
curl -u apiuser:apipass -H "Content-Type: application/json" \
-d '{"tdid":"XXXX"}' \
"https://push.n01darts.com/api/v1/league/schedule/generate"
# Standings
curl "https://push.n01darts.com/api/v1/tournament/standings?tdid=XXXX"
9. Live samples
This manual is served by the API server itself, so the links below call the actual API on the same server. Clicking a URL opens the resulting JSON in a new tab. Clicking "Run" shows the formatted result at the bottom of this page.
| Sample | Description | |
|---|---|---|
health |
Health check | |
tournament/list?count=5 |
Latest 5 tournaments | |
tournament/list?status__in=20,30&sort=updateTime&count=5 |
5 open/in-progress tournaments by update time | |
league/list?count=5 |
Latest 5 leagues | |
match/list?count=5 |
Latest 5 matches | |
match/list?match_type=cricket&count=5 |
5 Cricket matches |
Using the tdid / lgid / mid values found in the list results,
you can try tournament/get?tdid=... and match/get?mid=... in the browser
address bar the same way.
10. MCP server
The API server also works as an MCP (Model Context Protocol) server, so AI agents such as Claude Code can call this API directly as tools. The transport is Streamable HTTP with a single endpoint.
POST /api/v1/mcp
- Authentication is the same Basic authentication as the REST API, or OAuth 2.1.
Without credentials only the data retrieval tools are exposed and they return the same data as
the public pages. When authenticated, the administration items of the competitions administered by the
authenticated user are included, and the create / update / delete tools become available
(an API user without
admin_iddoes not get the write tools; 5. Authentication). Wrong credentials are rejected with HTTP 401. - Calls that use Basic authentication require an API subscription, exactly like the REST API.
Without one, or once it has expired, the tool result carries
result: -42(the connection itself stays open). - Every tool returns the same JSON as the corresponding REST API. The arguments use the same names
as the query parameters / request body of the REST API (list filters take the
common list parameters as they are, e.g.
status__in: "20,30"). Aresultother than 0 is reported as a tool error (isError). - Every tool carries
annotations(readOnlyHint/destructiveHint/idempotentHint/openWorldHint). The data retrieval tools are read only, the create tools only add data, and the update / delete tools are reported as destructive because they replace or remove existing data. - The server is stateless (no
Mcp-Session-Idis issued). Responses are always JSON and no server-initiated stream (SSE) is used. The supported protocol versions are2025-06-18and2025-03-26.
Tools
Data retrieval (authentication optional)
| Tool | REST API |
|---|---|
n01_health | /api/v1/health |
n01_tournament_list | /api/v1/tournament/list |
n01_tournament_get | /api/v1/tournament/get |
n01_tournament_entry_list | /api/v1/tournament/entry/list |
n01_tournament_stats | /api/v1/tournament/stats |
n01_league_list | /api/v1/league/list |
n01_league_get | /api/v1/league/get |
n01_league_entry_list | /api/v1/league/entry/list |
n01_league_tournament_list | /api/v1/league/tournament/list |
n01_match_list | /api/v1/match/list |
n01_match_get | /api/v1/match/get |
n01_team_order_list | /api/v1/team/order/list |
n01_team_player_list | /api/v1/team/player/list |
n01_tournament_standings | /api/v1/tournament/standings |
n01_tournament_end_group | /api/v1/tournament/end_group |
n01_league_schedule_get | /api/v1/league/schedule/get |
n01_league_stats | /api/v1/league/stats |
n01_autopilot_get | /api/v1/autopilot/get (administrator authentication required) |
n01_autopilot_list | /api/v1/autopilot/list (administrator authentication required) |
Create / update / delete (Basic authentication or OAuth; not listed on unauthenticated connections)
| Tool | REST API |
|---|---|
n01_tournament_create | /api/v1/tournament/create |
n01_tournament_update | /api/v1/tournament/update |
n01_tournament_delete | /api/v1/tournament/delete |
n01_tournament_entry_update | /api/v1/tournament/entry/update |
n01_league_create | /api/v1/league/create |
n01_league_update | /api/v1/league/update |
n01_league_delete | /api/v1/league/delete |
n01_league_entry_update | /api/v1/league/entry/update |
n01_match_create | /api/v1/match/create |
n01_match_update | /api/v1/match/update |
n01_match_delete | /api/v1/match/delete |
n01_team_player_update | /api/v1/team/player/update |
n01_team_order_update | /api/v1/team/order/update |
n01_team_order_fix | /api/v1/team/order/fix |
n01_team_order_result | /api/v1/team/order/result |
n01_tournament_result_update | /api/v1/tournament/result/update |
n01_league_schedule_update | /api/v1/league/schedule/update |
n01_league_schedule_generate | /api/v1/league/schedule/generate |
n01_league_tournament_link | /api/v1/league/tournament/link |
n01_league_tournament_unlink | /api/v1/league/tournament/unlink |
n01_tournament_badge_update | /api/v1/tournament/badge/update |
n01_tournament_memo_update | /api/v1/tournament/memo/update |
n01_tournament_t_memo_update | /api/v1/tournament/t_memo/update |
n01_tournament_announce_update | /api/v1/tournament/announce/update |
n01_tournament_assign_update | /api/v1/tournament/assign/update |
n01_tournament_copy | /api/v1/tournament/copy |
n01_tournament_match_release | /api/v1/tournament/match/release |
n01_autopilot_update | /api/v1/autopilot/update |
Connecting from Claude Code
# read only (no authentication)
claude mcp add --transport http n01 https://push.n01darts.com/api/v1/mcp
# with updates (Basic authentication)
claude mcp add --transport http n01 https://push.n01darts.com/api/v1/mcp \
--header "Authorization: Basic $(printf '%s' 'apiuser:apipass' | base64)"
To share the configuration in a project, put it in .mcp.json (pass the credentials through an
environment variable).
{
"mcpServers": {
"n01": {
"type": "http",
"url": "https://push.n01darts.com/api/v1/mcp",
"headers": {"Authorization": "Basic ${N01_API_BASIC}"}
}
}
}
Connecting from claude.ai
In claude.ai open Settings → Connectors → "Add custom connector" and register the URL
https://push.n01darts.com/api/v1/mcp. Choose OAuth as the authentication: the n01 login page
opens, and after you log in with the account you administer your competitions with and allow the access,
the create / update / delete tools are available as that administrator (OAuth 2.1).
Registered without authentication, only the data retrieval tools are available.