AbraTabia Game Server API Reference
join to enter matchmaking or a lobby, status to poll for a match, action to send a move, actions to receive everyone's moves, and leave to exit the queue. This page documents every request and response field on all five. If you have not installed the server yet, start with getting started.
Authentication and Request Format
All endpoints are POST with a JSON body, and a form post works too. Send your key in the X-API-Key header, or as an apiKey field in the body. Paths use path info, and if your server does not support that, api.php?action=join works the same as api.php/join. Every endpoint can also answer in a plain text split-string format for older clients, covered in the Unity and legacy protocol guide.
POST api.php/join
Join public matchmaking, or open or join a private lobby.
curl -X POST https://yourserver.com/api.php/join \
-H "Content-Type: application/json" \
-H "X-API-Key: YOUR_KEY" \
-d '{"playerid": "player-abc123", "gameMode": "1V1", "numPlayers": 2, "username": "Paul"}'
| Field | Notes |
|---|---|
playerid | Required. Your client's unique ID for this player, 3 or more characters. |
gameMode | One mode or several joined with &, like "1V1&2V2". Players match when they share a mode. Default "1V1". |
numPlayers | How many players this match should have, 2 up to the configured maximum, default 2. |
username | Optional display name shared with the other players. |
playerInfo, talentInfo, charInfo | Optional opaque strings shared with the other players, for loadouts, decks, skins, whatever your game needs. |
private | Send "1" to open a private lobby instead of public matchmaking. |
joinCode | Join an open private lobby by its code. With private: "1" and no code, the server generates one for you. |
timeLimit | Optional string stored on the match for your clients to read. |
The response is either a matched object, described below, when enough compatible players were already waiting, or a waiting status:
{"status": "waiting", "numPlayers": 2}
Private lobbies also return joinCode and playersWaiting. After a waiting response, poll status every couple of seconds. The & in multi-mode strings is a literal ampersand, and the design thinking behind modes, party sizes, and codes is covered in private matches and modes.
POST api.php/status
Where is this player right now? One field: playerid. The response is one of three shapes:
| Response | Meaning |
|---|---|
| A matched object | The player is in a match, same shape join returns when a match forms. |
{"status": "waiting", ...} | Still in the queue. Private lobbies include joinCode and playersWaiting. |
{"status": "none"} | Not in a queue or match, either the entry expired or the player never joined. Re-join to try again. |
Status doubles as reconnection: a client that lost its connection asks where it is, gets the matched object back, and re-pulls the full action log with since: 0 to rebuild the game.
The Matched Object
{
"status": "matched",
"matchid": "g17529339421234",
"gameMode": "1V1",
"numPlayers": 2,
"yourPlayerNum": 1,
"timeLimit": "0",
"private": 0,
"joinCode": "",
"lastActionID": 0,
"players": [
{"playerNum": 0, "username": "Paul", "playerInfo": "", "talentInfo": "", "charInfo": ""},
{"playerNum": 1, "username": "Ana", "playerInfo": "", "talentInfo": "", "charInfo": ""}
]
}
yourPlayerNum is this player's slot, and the players array carries every player's display name and the three optional info strings from their join call. A common convention is that slot 0 moves first, and that call belongs to your game.
POST api.php/action
Send one game action to a match.
curl -X POST https://yourserver.com/api.php/action \
-H "Content-Type: application/json" \
-H "X-API-Key: YOUR_KEY" \
-d '{"playerid": "player-abc123", "matchid": "g17529339421234", "actionType": "move", "data1": "e2e4"}'
| Field | Notes |
|---|---|
playerid, matchid | Required. Who is acting, in which match. |
actionType | Required. Any string your game defines: move, chat, quit, drawOffer, emote. |
data1, data2, data3 | Optional opaque strings. The server stores and delivers them without interpreting them. |
totalTime | Optional string for clocks and timers, delivered with the action. |
Returns {"status": "ok", "actionID": 1752933999}. Action IDs increase permanently within a match, which is what gives every client the same ordering.
POST api.php/actions
Poll for actions newer than the last one this client has. Fields: matchid, and since, the highest actionID already received, 0 for everything.
{"status": "ok", "count": 1, "lastActionID": 1752933999, "actions": [
{"actionID": 1752933999, "player": 0, "actionType": "move", "data1": "e2e4", "data2": "", "data3": "", "totalTime": "0"}
]}
Send the returned lastActionID as since on the next poll. The list includes your own actions too, which doubles as delivery confirmation. Polling every 1 to 3 seconds is plenty for turn-based games, and each poll is an ordinary HTTPS request that returns instantly.
POST api.php/leave
Leave the matchmaking queue. One field: playerid. Returns {"status": "left"}. Leaving a match already in progress is a game-level event, so send an action your game defines, like actionType: "quit", and the other players hear about it through the action log.
The Flow at a Glance
- Each client joins with a
playeridyou generate, agameMode, and anumPlayers. - Clients that get
waitingpollstatusuntil they get a matched object. - Everyone learns their
yourPlayerNumand the other players' info from the matched object. - Players take turns: send an
action, and pollactionsto receive everyone's moves in order. - Your clients decide what actions mean, whose turn it is, and when the game ends.
To see all five calls working together in real code, the build a game walkthrough steps through the complete tic tac toe demo client.
Five POST endpoints run the whole show: join enters a queue or lobby, status polls until a match forms, action sends a move with three opaque data fields, actions delivers every move to every player in order, and leave exits the queue. Send your API key with each call and your game has multiplayer.