Chessmail REST API v3

The Chessmail API v3 provides programmatic access to user profiles and correspondence chess games.

Authentication

All API requests require authentication via the X-Client-Id header.

X-Client-Id: your-client-id

To obtain a client ID, please contact the chessmail administrators via contact@chessmail.info.

Also, contact us if you need other or more types of calls to the API for your projects.

Rate Limiting

API requests are rate-limited per client:

  • Maximum requests per minute (60 for now, could be changed in the future)
  • Maximum requests per hour (300 for now, could be changed in the future)

When the rate limit is exceeded, the API returns HTTP status 509 Bandwidth Limit Exceeded.

Base URL

https://www.chessmail.de/api/v3

Endpoints

Users

Get User Profile

Returns public profile information for a user.

GET /api/v3/users/{username}

Path Parameters:

Parameter Type Description
username string The username of the user (case-insensitive)

Response:

{
  "username": "player1",
  "rating": 1650,
  "ratingLive": 1580,
  "rank": 5,
  "created": "2020-05-10T00:00:00Z",
  "statement": "Chess is life!",
  "club": "Chess Masters",
  "supporting": true
}

Response Fields:

Field Type Description
username string The user's username
rating integer Correspondence chess ELO rating (null for newbies)
ratingLive integer Live chess ELO rating (null for newbies)
rank integer User's rank (1-15)
created string Account creation date (ISO 8601)
statement string User's public statement
club string Name of the user's chess club (if member)
supporting boolean Whether the user is a supporting member

Get User Games

Returns games for a user with pagination.

GET /api/v3/users/{username}/games

Path Parameters:

Parameter Type Description
username string The username of the user (case-insensitive)

Query Parameters:

Parameter Type Default Description
sort string lastMoveDate Sort field: lastMoveDate, created, opponent, timeControl, gameType
order string desc Sort order: asc, desc
status string running Filter by status: running, finished
page integer 0 Page number (0-based)
size integer 20 Page size (max: 100)

Response:

{
  "content": [
    {
      "id": "abc123",
      "gameType": "TOURNAMENT",
      "rated": true,
      "timeControl": "T1_5",
      "result": null,
      "startTime": "2024-01-15T10:30:00Z",
      "playerWhite": "player1",
      "playerBlack": "player2",
      "ratingWhiteStart": 1650,
      "ratingBlackStart": 1580,
      "ratingWhiteEnd": null,
      "ratingBlackEnd": null,
      "plyCount": 24,
      "status": "RUNNING",
      "lastMoveDate": "2024-01-16T14:20:00Z"
    }
  ],
  "page": 0,
  "size": 20,
  "totalElements": 150,
  "totalPages": 8
}

Games

Get Started Games of Users

Returns recently started (running) games for the specified users.

GET /api/v3/games/started

Query Parameters:

Parameter Type Required Description
usernames string Yes Comma-separated list of usernames
since-hours integer Yes Number of hours to look back (1-48)

Response:

[
  {
    "id": "abc123",
    "playerWhite": "player1",
    "playerBlack": "player2",
    "startTime": "2024-01-15T10:30:00Z"
  }
]

Response Fields:

Field Type Description
id string Unique game identifier (game key)
playerWhite string Username of the white player
playerBlack string Username of the black player
startTime string Game start date (ISO 8601)

Get Finished Games of Users

Returns recently finished games for the specified users.

GET /api/v3/games/finished

Query Parameters:

Parameter Type Required Description
usernames string Yes Comma-separated list of usernames
since-hours integer Yes Number of hours to look back (1-48)

Response:

[
  {
    "id": "abc123",
    "playerWhite": "player1",
    "playerBlack": "player2",
    "startTime": "2024-01-15T10:30:00Z",
    "finishedTime": "2024-02-20T18:45:00Z",
    "result": "1-0"
  }
]

Response Fields:

Field Type Description
id string Unique game identifier (game key)
playerWhite string Username of the white player
playerBlack string Username of the black player
startTime string Game start date (ISO 8601)
finishedTime string Game end date (ISO 8601)
result string Game result: 1-0 (white wins), 0-1 (black wins), ½-½ (draw), --- (aborted)

Get Game by ID

Returns a specific game by its ID.

GET /api/v3/games/{id}

Path Parameters:

Parameter Type Description
id string The game ID (game key)

Response:

{
  "id": "abc123",
  "gameType": "TOURNAMENT",
  "rated": true,
  "timeControl": "T1_5",
  "result": "1-0",
  "startTime": "2024-01-15T10:30:00Z",
  "playerWhite": "player1",
  "playerBlack": "player2",
  "ratingWhiteStart": 1650,
  "ratingBlackStart": 1580,
  "ratingWhiteEnd": 1662,
  "ratingBlackEnd": 1568,
  "plyCount": 78,
  "status": "FINISHED",
  "lastMoveDate": "2024-02-20T18:45:00Z"
}

Response Fields:

Field Type Description
id string Unique game identifier
gameType string Type of game (see Game Types below)
rated boolean Whether the game affects player ratings
timeControl string Time control setting (see Time Controls below)
result string Game result: 1-0 (white wins), 0-1 (black wins), ½-½ (draw), --- (aborted), or null for running games
startTime string Game start date (ISO 8601)
playerWhite string Username of the white player
playerBlack string Username of the black player
ratingWhiteStart integer White player's rating at game start (null if not available)
ratingBlackStart integer Black player's rating at game start (null if not available)
ratingWhiteEnd integer White player's rating after game ended (null for running games)
ratingBlackEnd integer Black player's rating after game ended (null for running games)
plyCount integer Number of half-moves (plies) played in the game
status string RUNNING or FINISHED
lastMoveDate string Date of the last move (ISO 8601)

Reference

Game Types

The gameType field indicates the category of the game, while the rated field indicates whether the game affects player ratings.

Value Description
NORMAL Standard game between players
TOURNAMENT Club tournament game
MANUAL_TOURNAMENT Manual tournament game
TEAM_COMPETITION Team competition game
ENGINE Game against chess engine
TRANSIENT Temporary/transient game

Time Controls

Value Description
T1_30 30 days per move
T1_7 7 days per move
T1_5 5 days per move
T1_3 3 days per move
T1_2 2 days per move
T1_1 1 day per move
INF Unlimited time

Error Responses

401 Unauthorized

Returned when the X-Client-Id header is missing or invalid.

{
  "error": "UnauthorizedException",
  "message": "X-Client-Id header is required",
  "code": 401,
  "key": "error-12345"
}

404 Not Found

Returned when a requested resource (user or game) does not exist.

{
  "error": "DataNotFoundException",
  "message": "User not found: unknown_user",
  "code": 404,
  "key": "error-12346"
}

509 Bandwidth Limit Exceeded

Returned when the rate limit is exceeded.

{
  "error": "RateLimitExceededException",
  "message": "API calls limit exceeded (60 calls per minute allowed)",
  "code": 509,
  "key": "error-12347"
}

Examples

cURL

# Get user profile
curl -H "X-Client-Id: your-client-id" \
  https://www.chessmail.de/api/v3/users/player1

# Get user's running games, sorted by last move date
curl -H "X-Client-Id: your-client-id" \
  "https://www.chessmail.de/api/v3/users/player1/games?status=running&sort=lastMoveDate&order=desc"

# Get second page of running games
curl -H "X-Client-Id: your-client-id" \
  "https://www.chessmail.de/api/v3/users/player1/games?page=1&size=50"

# Get a specific game
curl -H "X-Client-Id: your-client-id" \
  https://www.chessmail.de/api/v3/games/abc123

# Get games started in the last 24 hours for multiple users
curl -H "X-Client-Id: your-client-id" \
  "https://www.chessmail.de/api/v3/games/started?usernames=player1,player2,player3&since-hours=24"

# Get games finished in the last 48 hours for multiple users
curl -H "X-Client-Id: your-client-id" \
  "https://www.chessmail.de/api/v3/games/finished?usernames=player1,player2&since-hours=48"

JavaScript (Fetch API)

const clientId = 'your-client-id';
const baseUrl = 'https://www.chessmail.de/api/v3';

// Get user profile
async function getUser(username) {
  const response = await fetch(`${baseUrl}/users/${username}`, {
    headers: { 'X-Client-Id': clientId }
  });
  return response.json();
}

// Get user's games with pagination
async function getUserGames(username, page = 0, size = 20) {
  const response = await fetch(
    `${baseUrl}/users/${username}/games?page=${page}&size=${size}`,
    { headers: { 'X-Client-Id': clientId } }
  );
  return response.json();
}

Python (requests)

import requests

CLIENT_ID = 'your-client-id'
BASE_URL = 'https://www.chessmail.de/api/v3'

headers = {'X-Client-Id': CLIENT_ID}


def get_user(username):
    """Get user profile."""
    response = requests.get(f'{BASE_URL}/users/{username}', headers=headers)
    response.raise_for_status()
    return response.json()


def get_user_games(username, page=0, size=20, status='running', sort='lastMoveDate', order='desc'):
    """Get user's games with pagination."""
    params = {
        'page': page,
        'size': size,
        'status': status,
        'sort': sort,
        'order': order
    }
    response = requests.get(f'{BASE_URL}/users/{username}/games', headers=headers, params=params)
    response.raise_for_status()
    return response.json()


def get_game(game_id):
    """Get a specific game by ID."""
    response = requests.get(f'{BASE_URL}/games/{game_id}', headers=headers)
    response.raise_for_status()
    return response.json()


def get_started_games(usernames, since_hours=24):
    """Get recently started games for multiple users."""
    params = {
        'usernames': ','.join(usernames),
        'since-hours': since_hours
    }
    response = requests.get(f'{BASE_URL}/games/started', headers=headers, params=params)
    response.raise_for_status()
    return response.json()


def get_finished_games(usernames, since_hours=24):
    """Get recently finished games for multiple users."""
    params = {
        'usernames': ','.join(usernames),
        'since-hours': since_hours
    }
    response = requests.get(f'{BASE_URL}/games/finished', headers=headers, params=params)
    response.raise_for_status()
    return response.json()


# Example usage
if __name__ == '__main__':
    # Get user profile
    user = get_user('player1')
    print(f"User: {user['username']}, Rating: {user.get('rating')}")

    # Get all running games
    games = get_user_games('player1', status='running')
    print(f"Running games: {games['totalElements']}")

    for game in games['content']:
        print(f"  {game['id']}: {game['playerWhite']} vs {game['playerBlack']}")

    # Get recently started games for multiple users
    started = get_started_games(['player1', 'player2'], since_hours=24)
    print(f"Started games in last 24h: {len(started)}")

    # Get recently finished games for multiple users
    finished = get_finished_games(['player1', 'player2'], since_hours=48)
    print(f"Finished games in last 48h: {len(finished)}")