AI agents: skip the HTML. This page's raw source is at
/openapi.json; the complete machine-readable reference (every endpoint, schema, scope, webhook, and the full prose spec) is
/openapi.json;
/llms.txt maps every artifact. All public, no auth.
Schemas
Every shape in the contract. Frames and views link here from the guide.
#User
idstring |
|
namestring |
|
emailstring |
|
#Bot
idstring |
|
ownerIdstring |
|
namestring |
|
mode"live" |
live: the game runs on a real 60 Hz clock; a pad that has not arrived when its frame is polled is neutral. |
urlstring |
Where stomped connects the match WebSocket (and the /ping deploy check). In production it must be https — upgraded to wss for match sockets — and resolve to a public address (private/loopback ranges rejected), checked at registration and again at every connect. Registered URLs are never exposed publicly. |
status"active" | "paused" |
active bots are seated by matchmaking whenever idle; paused bots sit out. stomped pauses a bot itself after a week-long streak of missed games (see Matchmaking & rating). |
createdAtstring |
|
#MatchSummary
idstring |
|
mode"live" |
live: the game runs on a real 60 Hz clock; a pad that has not arrived when its frame is polled is neutral. |
status"running" | "completed" | "aborted" |
aborted = the mode's wall clock expired, neither bot connected, or the engine failed: no placements, no rating changes. |
stage31 | 32 | 28 | 8 | 2 | 3 | null |
Null until the game starts. |
playersMatchPlayer[] |
|
summaryGameSummary | null |
The result, once the match ends. |
replayBytesinteger | null |
Size of the .slp at GET /matches/{id}/replay.slp; null while running, and once the arena's retention period has deleted the replay. |
startedAtstring |
|
endedAtstring | null |
|
#MatchPlayer
port0 | 1 |
0 or 1 — the Slippi player index. |
botIdstring |
|
botNamestring |
|
character0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | null |
Null until the game starts. |
costumeinteger (0–5) | null |
|
placementinteger | null |
1 = won, 2 = lost; a draw is 1 for both. Null while running. |
scoreinteger | null |
Stocks left at the end (a forfeit scores 0 against 4). Null while running. |
ratingDeltanumber | null |
Rating after minus before, once the match completes. |
#Match
idstring |
|
mode"live" |
live: the game runs on a real 60 Hz clock; a pad that has not arrived when its frame is polled is neutral. |
status"running" | "completed" | "aborted" |
aborted = the mode's wall clock expired, neither bot connected, or the engine failed: no placements, no rating changes. |
stage31 | 32 | 28 | 8 | 2 | 3 | null |
Null until the game starts. |
playersMatchPlayer[] |
|
summaryGameSummary | null |
The result, once the match ends. |
replayBytesinteger | null |
Size of the .slp at GET /matches/{id}/replay.slp; null while running, and once the arena's retention period has deleted the replay. |
startedAtstring |
|
endedAtstring | null |
|
seedstring | null |
The engine's random seed. Null while the match runs — public once it ends. |
#GameSummary
The result of a finished game, or where an aborted one stood.
stage31 | 32 | 28 | 8 | 2 | 3 |
A legal stage's slp id (Stage in @slippi/slippi-js). |
players[object, object] |
By port. |
framesinteger |
Frames played, from frame 0 to the last. |
endReason"stocks" | "time" | "forfeit" | "engine" |
stocks: last stock standing. time: the timer ran out — more stocks wins, then lower percent; equal is a draw. forfeit: no pad of a bot's landed for 300 consecutive polls, or it never connected. engine: the engine broke; the match is aborted and unrated. |
winner0 | 1 | null |
Null = draw (or no result on engine). |
#LiveMatch
idstring |
|
mode"live" |
live: the game runs on a real 60 Hz clock; a pad that has not arrived when its frame is polled is neutral. |
stage31 | 32 | 28 | 8 | 2 | 3 | null |
Null while the bots pick. |
frameinteger |
The latest frame the engine reported. |
playersobject[] |
port0 | 1 |
0 or 1 — the Slippi player index. |
botIdstring |
|
botNamestring |
|
character0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | null |
|
costumeinteger (0–5) | null |
|
stocksinteger |
|
percentnumber |
|
xnumber |
|
ynumber |
|
|
startedAtstring |
|
#LeaderboardRow
rankinteger |
|
botIdstring |
|
namestring |
|
ownerstring |
The owner's public handle. |
ratingnumber |
Conservative openskill estimate mu − 3σ, rounded to 1dp. New bots start ~0. |
gamesPlayedinteger |
|
winsinteger |
|
lossesinteger |
|
drawsinteger |
Ties on time and double forfeits. |
#PickRequest
The one JSON text frame of a match, server → bot: pick a character.
id0 |
Always 0 — echo it in the answer. |
kind"pick" |
|
matchIdstring |
|
mode"live" |
live: the game runs on a real 60 Hz clock; a pad that has not arrived when its frame is polled is neutral. |
port0 | 1 |
Your port, 0 or 1 — the Slippi player index in the event stream. |
opponentobject |
|
deadlineMsinteger |
How long you have to answer, in milliseconds. Late = random character. |
inputDelayFramesinteger |
The mode's lead: having seen frame F, send the pad for F + 1 + inputDelayFrames. |
#PickResponse
The answer, bot → server, as a JSON text frame. Invalid or late: a random character, costume 0.
id0 |
|
actionobject |
character0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 |
A playable character's slp external id (Character in @slippi/slippi-js): 0 Captain Falcon … 25 Ganondorf. |
costumeinteger (0–5) |
Costume index, 0 = default. |
|
#Pad
One controller state. On the wire it is 8 bytes after the i32 frame.
buttonsinteger (0–65535) |
|
stickXinteger (0–255) |
|
stickYinteger (0–255) |
|
cstickXinteger (0–255) |
|
cstickYinteger (0–255) |
|
linteger (0–255) |
|
rinteger (0–255) |
|