BYTETOOLS

Lichess API

Free Lichess API with no key for public data: player profiles, ratings, game archives in PGN, tournaments, puzzles and opening explorer. Tested example.

No API key requiredCORS enabledHTTPSFree tier

Endpoint tested and returned HTTP 200 on 2026-08-20

What is the Lichess API?

The Lichess API is a free, key-free API for the open-source chess platform, providing player profiles and ratings, complete game archives in PGN or JSON, tournaments, puzzles and an opening explorer over millions of games.

Lichess is free and open source with no advertising, and its API reflects that ethos: public data needs no authentication, and there is no commercial tier gating the useful parts.

The opening explorer is the standout feature — it aggregates millions of games to show move frequencies and win rates from any position, which is the kind of data chess engines and paid databases normally charge for.

Quick facts

Base URL
https://lichess.org/api
Authentication
Public data needs no auth. Playing, and accessing private data, requires an OAuth token.
Rate limit
Varies by endpoint; roughly 20 requests per second, with stricter limits on game downloads.
Pricing
Free and open source, funded by donations.
CORS
Enabled — callable directly from browser JavaScript
Official docs
Read the docs

How to use the Lichess API

Every request below was executed against the live API on 2026-08-20, and the response shown is the real body it returned — not an illustration.

1. Fetch a player's profile and ratings

GET https://lichess.org/api/user/thibault

curl
curl 'https://lichess.org/api/user/thibault'
JavaScript (fetch)
const res = await fetch("https://lichess.org/api/user/thibault");
if (!res.ok) throw new Error(`Request failed: ${res.status}`);
const data = await res.json();
console.log(data);
Python (requests)
import requests

res = requests.get("https://lichess.org/api/user/thibault", timeout=20)
res.raise_for_status()
print(res.json())
Response — HTTP 200 (truncated)
{
  "id": "thibault",
  "username": "thibault",
  "perfs": {
    "ultraBullet": {
      "games": 3,
      "rating": 1688,
      "rd": 361,
      "prog": 0,
      "prov": true
    },
    "bullet": {
      "games": 7483,
      "rating": 1774,
      "rd": 95,
      "prog": -22
    },
    "blitz": {
      "games": 11721,
      "rating": 1737,
      "rd": 52,
      "prog": 25
    },
    "rapid": {
      "games": 913,
      "rating": 1802,
      "rd": 65,
      "prog": -100
    },
    "classical": {
      "games": 25,
      "rating": 1858,
      "rd": 246,
      "prog": 48,
      "prov": true
    },
    "correspondence": {
      "games": 377,
      "rating": 1942,
      "rd": 172,
      "prog": -12,
      "prov": true
    },
    "chess960": {
      "games": 348,
      "rating": 1551,
      "rd": 269,
      "prog": 61,
      "prov": true
    },
    "kingOfTheHill": {
      "games": 94,
      "rating": 1744,
      "rd": 288,
      "prog": 14,
      "prov": true
    },
    "threeCheck": {
      "games": 66,
      "rating": 1728,
      "rd": 261,
      "prog": 132,
      "prov": true
    },
    "antichess": {
      "games": 73,
      "rating": 1465,
      "rd": 253,
      "prog": -56,
      "prov": true
    },
    "atomic": {
      "games": 99,
      "rating": 1633,
      "rd": 301,
      "prog": 18,
      "prov": true
    },
    "horde": {
      "games": 46,
      "rating": 1592,
      "rd": 282,
      "prog": -20,
      "prov": true
    },
    "racingKings": {
      "games": 13,
      "rating": 1552,
      "rd": 332,
      "prog": -75,
      "prov": true
    },
    "crazyhouse": {

Parameters

ParameterTypeRequiredDescription
user/<username>pathOptionalPlayer profile and ratings. user/thibault
games/user/<username>pathOptionalA player's game archive, streamed as NDJSON or PGN. games/user/thibault
maxintegerOptionalMaximum games to return. 10
AcceptheaderOptionalapplication/x-ndjson for JSON games, application/x-chess-pgn for PGN. application/x-ndjson

Response fields

id / usernamestring
Player identifier.
perfsobject
Ratings per time control — bullet, blitz, rapid, classical, puzzle.
perfs.<variant>.ratinginteger
Glicko-2 rating for that variant.
perfs.<variant>.provboolean
True when the rating is provisional from too few games.
countobject
Total games played, won, lost and drawn.
createdAt / seenAtinteger
Account creation and last seen, as Unix milliseconds.

What you can build with the Lichess API

  • Build a chess statistics or rating tracker
  • Download and analyse a player's game archive
  • Study opening theory with the explorer endpoint
  • Create chess training tools using the puzzle database

Common errors and how to fix them

Game downloads return NDJSON, not JSON

Archives are streamed newline-delimited.

Fix: Parse line by line rather than as a single JSON document — archives can be enormous.

429

Rate limited, especially on game downloads.

Fix: Respect the limits; Lichess is donation-funded. Add delays and cache.

Provisional ratings

prov: true means too few games for a reliable rating.

Fix: Do not present provisional ratings as established strength.

Lichess API — frequently asked questions

Is the Lichess API free?

Yes, completely free with no API key for public data. Lichess is open source and donation-funded, with no commercial tier.

Can I download a player's games?

Yes, the archive endpoint streams every game as NDJSON or PGN. Because archives can run to hundreds of thousands of games, parse them line by line rather than loading the whole response.

What is the opening explorer?

An endpoint aggregating millions of games to show which moves are played from any position and their win rates — the kind of data commercial chess databases charge for.

Do I need a token?

Only to play games or access private data. Profiles, ratings, public games and the explorer are all anonymous.

Tools that pair with this API

Lichess is an independent third-party service and is not affiliated with ByteTools or ByteVancer. Details on this page were verified on 2026-08-20; always check the official documentation before relying on this API in production, as terms and limits can change.