How to Use the Chess.com API in Python

Sort:
AlAlper

🧠 How to Use the Chess.com API in Python — With Headers & Real Examples♟️🐍

So what do you want to do with the Chess.com API?

You can pull user profiles, ratings, games, tournament participants, and more. The data is all public, and it's a great way to build analysis tools, or club automation systems.


⚠️ Why You Need Custom Headers

Before we jump into the code, here’s a critical tip:
Always include headers in your API requests.

Chess.com uses rate limiting and spam prevention. If you skip the headers, you’ll be Forbidden.

  • 403 Forbidden (Access denied)

If do do to much to fast you will get.

  • 429 Too Many Requests (You’ve hit the rate limit)

Adding a proper User-Agent with your app name and contact info tells their system:

“Hey, I’m not a bot. I’m a human using this responsibly. Here’s how to reach me.”


🧰 Setup: Define Your Custom Headers in Python

We'll use an Enum to organize different headers for different purposes. This is optional but clean and scalable:

from enum import Enum
import requests

# 🧠 Define headers for each type of API call
class Api_Headers(Enum):
    ACTIVE_PLAYERS = {
        "User-Agent": "GT-Active-Players-App/1.0 (Python 3.9.13) -- Finds daily players. (contact- BEST @YourUsername on Chess.com or LEAST RELIABLE dev@example.com)",
        "Accept": "application/json",
        "Accept-Encoding": "gzip, deflate",
        "Connection": "keep-alive"
    }
    TOURNAMENT_PARTICIPANTS = {
        "User-Agent": "GT-Tournament-Participation-App/1.0 (Python 3.9.13) -- Gets tournament player list. (contact- BEST @YourUsername on Chess.com or LEAST RELIABLE dev@example.com)",
        "Accept": "application/json",
        "Accept-Encoding": "gzip, deflate",
        "Connection": "keep-alive"
    }
    USER_INFO = {
        "User-Agent": "GT-User-Info-App/1.0 (Python 3.9.13) -- Gets user info. (contact- BEST @YourUsername on Chess.com or LEAST RELIABLE dev@example.com)",
        "Accept": "application/json",
        "Accept-Encoding": "gzip, deflate",
        "Connection": "keep-alive"
    }

🧪 Example: Get the List of Players in a Tournament

Let’s say you want to get a list of usernames who joined a specific tournament.

📘 Endpoint:
https://api.chess.com/pub/tournament/{tournament-name}/players

Here’s a full Python function to do just that:

def get_tournament_usernames(tournament_name):
    """
    Queries the Chess.com public API to get the list of player usernames in a tournament.

    Parameters:
    tournament_name (str): The slug or URL-friendly name of the tournament
                           (e.g., 'gt-april-showers-knockout-1-1600').

    Returns:
    list: A list of usernames who are participants in the tournament.
    """

    # Build the full API URL using the tournament name
    url = f"https://api.chess.com/pub/tournament/{tournament_name}/players"

    # Make the GET request with headers to avoid rate-limiting or blocking
    response = requests.get(
        url,
        headers=Api_Headers.TOURNAMENT_PARTICIPANTS.value
    )

    # If the request fails (e.g., bad tournament or missing headers), print status
    if response.status_code != 200:
        print(f"⚠️ Failed to get players: HTTP {response.status_code}")
        return []

    # Convert the JSON API response into a Python dictionary
    data = response.json()

    # Extract the list of usernames from the response
    usernames = [
        player["username"]
        for player in data.get("players", [])
        if "username" in player
    ]

    return usernames

🧪 Try It Out:

players = get_tournament_usernames("gt-april-showers-knockout-1-1600")
print(players)

Output:

['ChessFan123', 'QueenCrusher', 'KnightRider89', ...]

✅ Summary

  • Headers matter: use User-Agent to avoid getting blocked.

  • The API is free and public — but you still need to be polite.

  • The data you can grab is super useful for clubs, tournaments, analysis, and automation.


💬 Got questions? Want to explore more endpoints like user stats, game history, or leaderboards? Drop a comment in this thread.