7.8 KiB
API Reference
Base URL: http://localhost:8080/api/v1
Content-Type: application/json (required for POST/PUT)
Authentication
The API supports optional JWT authentication for user accounts. When authenticated, games are associated with the user account.
Register User
POST /auth/register
Creates new user account and returns JWT token.
Request:
{
"username": "alice",
"email": "alice@example.com",
"password": "SecurePass123"
}
username(string, required): 1-40 characters, alphanumeric and underscore onlyemail(string, optional): Valid email addresspassword(string, required): Minimum 8 characters, must contain letter and number
Response (201):
{
"token": "eyJhbGciOiJIUzI1NiIs...",
"userId": "550e8400-e29b-41d4-a716-446655440000",
"username": "alice",
"email": "alice@example.com",
"expiresAt": "2025-01-14T10:30:00Z"
}
Login
POST /auth/login
Authenticates user and returns JWT token.
Request:
{
"identifier": "alice",
"password": "SecurePass123"
}
identifier(string, required): Username or email addresspassword(string, required): User password
Response (200):
{
"token": "eyJhbGciOiJIUzI1NiIs...",
"userId": "550e8400-e29b-41d4-a716-446655440000",
"username": "alice",
"email": "alice@example.com",
"expiresAt": "2025-01-14T10:30:00Z"
}
Get Current User
GET /auth/me
Returns authenticated user information. Requires authentication.
Headers:
Authorization: Bearer <token>
Response (200):
{
"userId": "550e8400-e29b-41d4-a716-446655440000",
"username": "alice",
"email": "alice@example.com",
"createdAt": "2025-01-07T10:30:00Z"
}
Game Endpoints
Health Check
GET /health
Returns server and storage status.
Response (200):
{
"status": "healthy",
"time": 1699123456,
"storage": "ok"
}
Storage states:
"disabled"- No storage path configured"ok"- Database operational with auth enabled"degraded"- A persistence write failed or the write queue filled; live games continue in memory, but durable history is no longer complete
The top-level status is also "degraded" when storage is degraded.
Create Game
POST /games
Creates new game with specified players. Optional authentication associates game with user.
Headers (optional):
Authorization: Bearer <token>
Request:
{
"white": {
"type": 1,
"level": 0,
"searchTime": 0
},
"black": {
"type": 2,
"level": 15,
"searchTime": 1000
},
"fen": "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"
}
Response (201):
{
"gameId": "a1b2c3d4-e5f6-7890-1234-567890abcdef",
"fen": "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1",
"turn": "w",
"state": "ongoing",
"moves": [],
"players": {
"white": {"id": "550e8400-...", "color": 1, "type": 1},
"black": {"id": "ai-player-...", "color": 2, "type": 2, "level": 15, "searchTime": 1000}
}
}
Note: When authenticated, human player IDs match the user's ID. Anonymous players receive unique UUIDs.
Get Game
GET /games/{gameId}
Returns current game state.
Long-polling support: Add query parameters for real-time updates:
wait=true- Enable long-polling (waits up to 30 seconds)moveCount=N- Last known move count
Returns immediately if game state changed, otherwise waits for updates:
GET /games/{gameId}?wait=true&moveCount=5
Response includes all game data. Compare moves array length to detect changes.
Timeout behavior:
- Returns current state after 30 seconds even if no changes
- Client disconnection cancels wait immediately
- Game deletion notifies all waiting clients
Get Durable Game History
GET /games/{gameId}/history
Returns the persisted replay line even after the live game has been unloaded from memory or the server has restarted. History is public to anyone who knows the game ID, matching the existing public live-game read model. Persistent storage must be enabled.
The response contains the initial FEN and an ordered FEN after every move, so a client can replay the game without running a chess engine.
Response (200):
{
"gameId": "a1b2c3d4-e5f6-7890-1234-567890abcdef",
"initialFen": "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1",
"result": "white_wins",
"startTimeUtc": "2026-09-07T12:00:00Z",
"endTimeUtc": "2026-09-07T12:15:00Z",
"players": {
"white": {"id": "user-id", "color": 1, "type": 1, "claimedBy": "user-id"},
"black": {"id": "player-id", "color": 2, "type": 1}
},
"moves": [
{
"moveNumber": 1,
"moveUci": "e2e4",
"fenAfterMove": "rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq - 0 1",
"playerColor": "w",
"moveTimeUtc": "2026-09-07T12:00:05Z"
}
]
}
result is omitted while a game is ongoing. Persisted terminal values are
white_wins, black_wins, draw, and stalemate.
Returns 404 when the game has no durable record and 503 when persistence is disabled.
List My Stored Games
GET /users/me/games?limit=50&offset=0
Returns games associated with the authenticated user at creation time or by a
later first-move slot claim. Requires Authorization: Bearer <token> and
persistent storage.
limit: 1-100; defaults to 50offset: 0-1,000,000; defaults to 0
Each item contains game ID, initial FEN, result/timestamps, players, and move
count. nextOffset is present only when another page exists.
Response (200):
{
"games": [
{
"gameId": "a1b2c3d4-e5f6-7890-1234-567890abcdef",
"initialFen": "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1",
"result": "white_wins",
"startTimeUtc": "2026-09-07T12:00:00Z",
"endTimeUtc": "2026-09-07T12:15:00Z",
"moveCount": 41,
"players": {
"white": {"id": "user-id", "color": 1, "type": 1, "claimedBy": "user-id"},
"black": {"id": "player-id", "color": 2, "type": 1}
}
}
],
"limit": 50,
"offset": 0
}
Make Move
POST /games/{gameId}/moves
Submits human move or triggers computer move.
Human move:
{"move": "e2e4"}
Computer move trigger:
{"move": "cccc"}
Undo Moves
POST /games/{gameId}/undo
Reverts moves from history.
Configure Players
PUT /games/{gameId}/players
Changes player configuration mid-game.
Get Board
GET /games/{gameId}/board
Returns ASCII board visualization.
Delete Game
DELETE /games/{gameId}
Unloads the live game from memory. Its persisted game and move history remain available through the history endpoint. Returns 204 on success.
Error Format
{
"error": "Description",
"code": "ERROR_CODE",
"details": "Additional context"
}
Error codes:
GAME_NOT_FOUND- Invalid game IDINVALID_MOVE- Illegal chess moveNOT_HUMAN_TURN- Wrong player type for turnGAME_OVER- Game already endedGAME_CONFLICT- Game changed while a move was being validated; refresh and retrySTORAGE_UNAVAILABLE- Durable history/list storage is disabled or degradedRATE_LIMIT_EXCEEDED- Request limit exceededINVALID_REQUEST- Malformed requestINVALID_CONTENT_TYPE- Missing/wrong Content-Type headerINVALID_FEN- Invalid FEN formatINTERNAL_ERROR- Server error
Rate Limiting
- Standard: 10 requests/second/IP (general endpoints)
- Development (
-dev): 20 requests/second/IP - Registration: 5 requests/minute/IP
- Login: 10 requests/minute/IP
Exceeding limit returns 429 status.
JWT Token Format
Tokens are HS256-signed JWTs valid for 7 days. Include in Authorization header:
Authorization: Bearer <token>
Token claims include sub (user ID), username, email, session_id, and
exp (expiration). Authentication requires the session to exist, be unexpired,
and belong to the JWT subject.