Lichess.org API reference (2.0.0)

Download OpenAPI specification:Download

Introduction

Welcome to the reference for the Lichess API! Lichess is free/libre, open-source chess server powered by volunteers and donations.

Endpoint

All requests go to https://lichess.org (unless otherwise specified).

Rate limiting

All requests are rate limited using various strategies, to ensure the API remains responsive for everyone. Only make one request at a time. If you receive an HTTP response with a 429 status, please wait a full minute before resuming API usage.

Streaming with ND-JSON

Some API endpoints stream their responses as Newline Delimited JSON a.k.a. nd-json, with one JSON object per line.

Here's a JavaScript utility function to help reading NDJSON streamed responses.

Authentication

Which authentication method is right for me?

Read about the Lichess API authentication methods and code examples

Personal Access Token

Personal API access tokens allow you to quickly interact with Lichess API without going through an OAuth flow.

Authorization Code Flow with PKCE

The authorization code flow with PKCE allows your users to login with Lichess. Lichess supports unregistered and public clients (no client authentication, choose any unique client id). The only accepted code challenge method is S256. Access tokens are long-lived (expect one year), unless they are revoked. Refresh tokens are not supported.

See the documentation for the OAuth endpoints or the PKCE RFC for a precise protocol description.

Real life examples

Token format

Access tokens and authorization codes match ^[A-Za-z0-9_]+$. The length of tokens can be increased without notice. Make sure your application can handle at least 512 characters. By convention tokens have a recognizable prefix, but do not rely on this.

Account

Read and write account information and preferences. https://lichess.org/account/preferences/game-display

Get my profile

Public information about the logged in user.

Authorizations:
OAuth2

Responses

Response samples

Content type
application/json
{
  • "id": "georges",
  • "username": "Georges",
  • "perfs": {
    },
  • "createdAt": 1290415680000,
  • "disabled": false,
  • "tosViolation": false,
  • "profile": {
    },
  • "seenAt": 1522636452014,
  • "patron": true,
  • "verified": true,
  • "playTime": {
    },
  • "title": "NM",
  • "count": {
    },
  • "streaming": false,
  • "streamer": {},
  • "followable": true,
  • "following": false,
  • "blocking": false,
  • "followsYou": false
}

Get my email address

Read the email address of the logged in user.

Authorizations:
OAuth2

Responses

Response samples

Content type
application/json
{
  • "email": "abathur@mail.org"
}

Get my preferences

Authorizations:
OAuth2

Responses

Response samples

Content type
application/json
{
  • "prefs": {
    },
  • "language": "en-GB"
}

Get my kid mode status

Read the kid mode status of the logged in user.

Authorizations:
OAuth2

Responses

Response samples

Content type
application/json
{
  • "kid": false
}

Set my kid mode status

Set the kid mode status of the logged in user.

Authorizations:
OAuth2
query Parameters
v
required
boolean
Example: v=true

Kid mode status

Responses

Response samples

Content type
application/json
{
  • "ok": true
}

Get my timeline

Get the timeline events of the logged in user.

Authorizations:
OAuth2
query Parameters
since
integer >= 1356998400070

Show events since this timestamp.

nb
integer [ 1 .. 30 ]
Default: 15

Max number of events to fetch.

Responses

Response samples

Content type
application/json
{
  • "entries": [
    ],
  • "users": {
    }
}

Users

Access registered users on Lichess. https://lichess.org/player

Get real-time users status

Read the online, playing and streaming flags of several users.

This API is very fast and cheap on lichess side. So you can call it quite often (like once every 5 seconds).

Use it to track players and know when they're connected on lichess and playing games.

query Parameters
ids
required
string
Example: ids=aliquantus,chess-network,lovlas

User IDs separated by commas. Up to 100 IDs.

withGameIds
boolean
Example: withGameIds=true

Also return the ID of the game being played, if any, for each player, in a playingId field. Defaults to false to preserve server resources.

Responses

Response samples

Content type
application/json
[
  • {
    },
  • {
    }
]

Get all top 10

Get the top 10 players for each speed and variant.

See https://lichess.org/player.

Responses

Response samples

Content type
application/json
{
  • "bullet": [
    ],
  • "blitz": [ ],
  • "rapid": [ ],
  • "classical": [ ],
  • "ultraBullet": [ ],
  • "chess960": [ ],
  • "crazyhouse": [ ],
  • "antichess": [ ],
  • "atomic": [ ],
  • "horde": [ ],
  • "kingOfTheHill": [ ],
  • "racingKings": [ ],
  • "threeCheck": [ ]
}

Get one leaderboard

Get the leaderboard for a single speed or variant (a.k.a. perfType). There is no leaderboard for correspondence or puzzles.

See https://lichess.org/player/top/200/bullet.

path Parameters
nb
required
integer [ 1 .. 200 ]
Example: 100

How many users to fetch

perfType
required
string
Enum: "ultraBullet" "bullet" "blitz" "rapid" "classical" "chess960" "crazyhouse" "antichess" "atomic" "horde" "kingOfTheHill" "racingKings" "threeCheck"
Example: bullet

The speed or variant

Responses

Response samples

Content type
application/vnd.lichess.v3+json
{
  • "users": [
    ]
}

Get user public data

Read public data of a user.

If the request is authenticated with OAuth2, then extra fields might be present in the response: followable, following, blocking, followsYou.

Authorizations:
OAuth2
path Parameters
username
required
string
query Parameters
trophies
boolean
Default: false

Include user trophies

Responses

Response samples

Content type
application/json
{
  • "id": "georges",
  • "username": "Georges",
  • "perfs": {
    },
  • "createdAt": 1290415680000,
  • "disabled": false,
  • "tosViolation": false,
  • "profile": {
    },
  • "seenAt": 1522636452014,
  • "patron": true,
  • "verified": true,
  • "playTime": {
    },
  • "title": "NM",
  • "count": {
    },
  • "streaming": false,
  • "streamer": {},
  • "followable": true,
  • "following": false,
  • "blocking": false,
  • "followsYou": false
}

Get rating history of a user

Read rating history of a user, for all perf types. There is at most one entry per day. Format of an entry is [year, month, day, rating]. month starts at zero (January).

path Parameters
username
required
string

Responses

Response samples

Content type
application/json
[
  • {
    },
  • {
    }
]

Get performance statistics of a user

Read performance statistics of a user, for a single performance. Similar to the performance pages on the website.

path Parameters
username
required
string
perf
required
string (PerfType)
Enum: "ultraBullet" "bullet" "blitz" "rapid" "classical" "correspondence" "chess960" "crazyhouse" "antichess" "atomic" "horde" "kingOfTheHill" "racingKings" "threeCheck"

Responses

Response samples

Content type
application/json
{
  • "perf": {
    },
  • "rank": 98121,
  • "percentile": 69.7,
  • "stat": {
    }
}

Get user activity

Read data to generate the activity feed of a user.

path Parameters
username
required
string

Responses

Response samples

Get users by ID

Get up to 300 users by their IDs. Users are returned in the same order as the IDs.

The method is POST to allow a longer list of IDs to be sent in the request body.

Please do not try to download all the Lichess users with this endpoint, or any other endpoint. An API is not a way to fully export a website. We do not provide a full download of the Lichess users.

This endpoint is limited to 8,000 users every 10 minutes, and 120,000 every day.

Request Body schema: text/plain
required

User IDs separated by commas.

string

Responses

Request samples

Content type
text/plain
aliquantus,chess-network,lovlas

Response samples

Content type
application/json
[
  • {
    }
]

Get live streamers

Get basic info about currently streaming users.

This API is very fast and cheap on lichess side. So you can call it quite often (like once every 5 seconds).

Responses

Response samples

Content type
application/json
[]

Get crosstable

Get total number of games, and current score, of any two users.

If the matchup flag is provided, and the users are currently playing, also gets the current match game number and scores.

path Parameters
user1
required
string
user2
required
string
query Parameters
matchup
boolean

Whether to get the current match data, if any

Responses

Response samples

Content type
application/json
{
  • "users": {
    },
  • "nbGames": 346,
  • "matchup": {
    }
}

Autocomplete usernames

Provides autocompletion options for an incomplete username.

query Parameters
term
required
string >= 3 characters

The beginning of a username

object
boolean
Default: false
  • false returns an array of usernames
  • true returns an object with matching users
friend
boolean

Returns followed players matching term if any, else returns other players. Requires OAuth.

Responses

Response samples

Content type
application/json
{
  • "result": [
    ]
}

Add a note for a user

Add a private note available only to you about this account.

Authorizations:
OAuth2
path Parameters
username
required
string
Example: thibault
Request Body schema: application/x-www-form-urlencoded
required
text
required
string

The contents of the note

Responses

Response samples

Content type
application/json
{
  • "ok": true
}

Get notes for a user

Get the private notes that you have added for a user.

Authorizations:
OAuth2
path Parameters
username
required
string
Example: thibault

Responses

Response samples

Content type
application/json
[
  • {
    }
]

Relations

Access relations between users.

Get users followed by the logged in user

Users are streamed as ndjson.

Authorizations:
OAuth2

Responses

Response samples

Content type
application/x-ndjson
{
  • "id": "georges",
  • "username": "Georges",
  • "perfs": {
    },
  • "createdAt": 1290415680000,
  • "disabled": false,
  • "tosViolation": false,
  • "profile": {
    },
  • "seenAt": 1522636452014,
  • "patron": true,
  • "verified": true,
  • "playTime": {
    },
  • "title": "NM",
  • "count": {
    },
  • "streaming": false,
  • "streamer": {},
  • "followable": true,
  • "following": false,
  • "blocking": false,
  • "followsYou": false
}

Follow a player

Follow a player, adding them to your list of Lichess friends.

Authorizations:
OAuth2
path Parameters
username
required
string
Example: thibault

Responses

Response samples

Content type
application/json
{
  • "ok": true
}

Unfollow a player

Unfollow a player, removing them from your list of Lichess friends.

Authorizations:
OAuth2
path Parameters
username
required
string
Example: thibault

Responses

Response samples

Content type
application/json
{
  • "ok": true
}

Games

Access games played on Lichess. https://lichess.org/games

Export one game

Download one game in either PGN or JSON format.

Ongoing games are delayed by a few seconds ranging from 3 to 60 depending on the time control, as to prevent cheat bots from using this API.

path Parameters
gameId
required
string

The game ID (8 characters).

query Parameters
moves
boolean
Default: true

Include the PGN moves.

pgnInJson
boolean
Default: false

Include the full PGN within the JSON response, in a pgn field.

tags
boolean
Default: true

Include the PGN tags.

clocks
boolean
Default: true

Include clock status when available.

Either as PGN comments: 2. exd5 { [%clk 1:01:27] } e5 { [%clk 1:01:28] }

Or in a clocks JSON field, as centisecond integers, depending on the response type.

evals
boolean
Default: true

Include analysis evaluations and comments, when available.

Either as PGN comments: 12. Bxf6 { [%eval 0.23] } a3 { [%eval -1.09] }

Or in an analysis JSON field, depending on the response type.

accuracy
boolean
Default: false

Include accuracy percent of each player, when available.

opening
boolean
Default: true

Include the opening name.

Example: [Opening "King's Gambit Accepted, King's Knight Gambit"]

division
boolean
Default: true

Plies which mark the beginning of the middlegame and endgame. Only available in JSON

literate
boolean
Default: false

Insert textual annotations in the PGN about the opening, analysis variations, mistakes, and game termination.

Example: 5... g4? { (-0.98 → 0.60) Mistake. Best move was h6. } (5... h6 6. d4 Ne7 7. g3 d5 8. exd5 fxg3 9. hxg3 c6 10. dxc6)

players
string

URL of a text file containing real names and ratings, to replace Lichess usernames and ratings in the PGN. Example: https://gist.githubusercontent.com/ornicar/6bfa91eb61a2dcae7bcd14cce1b2a4eb/raw/768b9f6cc8a8471d2555e47ba40fb0095e5fba37/gistfile1.txt

Responses

Response samples

Content type
No sample

Export ongoing game of a user

Download the ongoing game, or the last game played, of a user. Available in either PGN or JSON format.

Ongoing games are delayed by a few seconds ranging from 3 to 60 depending on the time control, as to prevent cheat bots from using this API.

path Parameters
username
required
string
query Parameters
moves
boolean
Default: true

Include the PGN moves.

pgnInJson
boolean
Default: false

Include the full PGN within the JSON response, in a pgn field.

tags
boolean
Default: true

Include the PGN tags.

clocks
boolean
Default: true

Include clock status when available.

Either as PGN comments: 2. exd5 { [%clk 1:01:27] } e5 { [%clk 1:01:28] }

Or in a clocks JSON field, as centisecond integers, depending on the response type.

evals
boolean
Default: true

Include analysis evaluations and comments, when available.

Either as PGN comments: 12. Bxf6 { [%eval 0.23] } a3 { [%eval -1.09] }

Or in an analysis JSON field, depending on the response type.

accuracy
boolean
Default: false

Include accuracy percent of each player, when available.

opening
boolean
Default: true

Include the opening name.

Example: [Opening "King's Gambit Accepted, King's Knight Gambit"]

division
boolean
Default: false

Plies which mark the beginning of the middlegame and endgame. Only available in JSON

literate
boolean
Default: false

Insert textual annotations in the PGN about the opening, analysis variations, mistakes, and game termination.

Example: 5... g4? { (-0.98 → 0.60) Mistake. Best move was h6. } (5... h6 6. d4 Ne7 7. g3 d5 8. exd5 fxg3 9. hxg3 c6 10. dxc6)

players
string

URL of a text file containing real names and ratings, to replace Lichess usernames and ratings in the PGN. Example: https://gist.githubusercontent.com/ornicar/6bfa91eb61a2dcae7bcd14cce1b2a4eb/raw/768b9f6cc8a8471d2555e47ba40fb0095e5fba37/gistfile1.txt

Responses

Response samples

Content type
No sample

Export games of a user

Download all games of any user in PGN or ndjson format.

Games are sorted by reverse chronological order (most recent first).

We recommend streaming the response, for it can be very long. https://lichess.org/@/german11 for instance has more than 500,000 games.

The game stream is throttled, depending on who is making the request:

  • Anonymous request: 20 games per second
  • OAuth2 authenticated request: 30 games per second
  • Authenticated, downloading your own games: 60 games per second
Authorizations:
OAuth2
path Parameters
username
required
string

The user name.

query Parameters
since
integer >= 1356998400070

Download games played since this timestamp. Defaults to account creation date.

until
integer >= 1356998400070

Download games played until this timestamp. Defaults to now.

max
integer >= 1

How many games to download. Leave empty to download all games.

vs
string

[Filter] Only games played against this opponent

rated
boolean

[Filter] Only rated (true) or casual (false) games

perfType
string
Default: null
Enum: "ultraBullet" "bullet" "blitz" "rapid" "classical" "correspondence" "chess960" "crazyhouse" "antichess" "atomic" "horde" "kingOfTheHill" "racingKings" "threeCheck"

[Filter] Only games in these speeds or variants.

Multiple perf types can be specified, separated by a comma.

Example: blitz,rapid,classical

color
string
Enum: "white" "black"

[Filter] Only games played as this color.

analysed
boolean

[Filter] Only games with or without a computer analysis available

moves
boolean
Default: true

Include the PGN moves.

pgnInJson
boolean
Default: false

Include the full PGN within the JSON response, in a pgn field. The response type must be set to application/x-ndjson by the request Accept header.

tags
boolean
Default: true

Include the PGN tags.

clocks
boolean
Default: false

Include clock status when available.

Either as PGN comments: 2. exd5 { [%clk 1:01:27] } e5 { [%clk 1:01:28] }

Or in a clocks JSON field, as centisecond integers, depending on the response type.

evals
boolean
Default: false

Include analysis evaluations and comments, when available.

Either as PGN comments: 12. Bxf6 { [%eval 0.23] } a3 { [%eval -1.09] }

Or in an analysis JSON field, depending on the response type.

accuracy
boolean
Default: false

Include accuracy percent of each player, when available.

opening
boolean
Default: false

Include the opening name.

Example: [Opening "King's Gambit Accepted, King's Knight Gambit"]

division
boolean
Default: false

Plies which mark the beginning of the middlegame and endgame. Only available in JSON

ongoing
boolean
Default: false

Ongoing games are delayed by a few seconds ranging from 3 to 60 depending on the time control, as to prevent cheat bots from using this API.

finished
boolean
Default: true

Include finished games. Set to false to only get ongoing games.

literate
boolean
Default: false

Insert textual annotations in the PGN about the opening, analysis variations, mistakes, and game termination.

Example: 5... g4? { (-0.98 → 0.60) Mistake. Best move was h6. } (5... h6 6. d4 Ne7 7. g3 d5 8. exd5 fxg3 9. hxg3 c6 10. dxc6)

lastFen
boolean
Default: false

Include the FEN notation of the last position of the game.

The response type must be set to application/x-ndjson by the request Accept header.

players
string

URL of a text file containing real names and ratings, to replace Lichess usernames and ratings in the PGN. Example: https://gist.githubusercontent.com/ornicar/6bfa91eb61a2dcae7bcd14cce1b2a4eb/raw/768b9f6cc8a8471d2555e47ba40fb0095e5fba37/gistfile1.txt

sort
string
Default: "dateDesc"
Enum: "dateAsc" "dateDesc"

Sort order of the games.

Responses

Response samples

Content type
No sample

Export games by IDs

Download games by IDs in PGN or ndjson format, depending on the request Accept header.

Games are sorted by reverse chronological order (most recent first)

The method is POST so a longer list of IDs can be sent in the request body.

300 IDs can be submitted.

Ongoing games are delayed by a few seconds ranging from 3 to 60 depending on the time control, as to prevent cheat bots from using this API.

query Parameters
moves
boolean
Default: true

Include the PGN moves.

pgnInJson
boolean
Default: false

Include the full PGN within the JSON response, in a pgn field.

tags
boolean
Default: true

Include the PGN tags.

clocks
boolean
Default: false

Include clock status when available.

Either as PGN comments: 2. exd5 { [%clk 1:01:27] } e5 { [%clk 1:01:28] }

Or in a clocks JSON field, as centisecond integers, depending on the response type.

evals
boolean
Default: false

Include analysis evaluations and comments, when available.

Either as PGN comments: 12. Bxf6 { [%eval 0.23] } a3 { [%eval -1.09] }

Or in an analysis JSON field, depending on the response type.

accuracy
boolean
Default: false

Include accuracy percent of each player, when available.

opening
boolean
Default: false

Include the opening name.

Example: [Opening "King's Gambit Accepted, King's Knight Gambit"]

division
boolean
Default: false

Plies which mark the beginning of the middlegame and endgame. Only available in JSON

literate
boolean
Default: false

Insert textual annotations in the PGN about the opening, analysis variations, mistakes, and game termination.

Example: 5... g4? { (-0.98 → 0.60) Mistake. Best move was h6. } (5... h6 6. d4 Ne7 7. g3 d5 8. exd5 fxg3 9. hxg3 c6 10. dxc6)

players
string

URL of a text file containing real names and ratings, to replace Lichess usernames and ratings in the PGN. Example: https://gist.githubusercontent.com/ornicar/6bfa91eb61a2dcae7bcd14cce1b2a4eb/raw/768b9f6cc8a8471d2555e47ba40fb0095e5fba37/gistfile1.txt

Request Body schema: text/plain
required

Game IDs separated by commas. Up to 300.

string

Responses

Request samples

Content type
text/plain
TJxUmbWK,4OtIh2oh,ILwozzRZ

Response samples

Content type
No sample

Stream games of users

Stream the games played between a list of users, in real time. Only games where both players are part of the list are included.

The stream emits an event each time a game is started or finished.

To also get all current ongoing games at the beginning of the stream, use the withCurrentGames flag.

Games are streamed as ndjson.

Maximum number of users: 300.

The method is POST so a longer list of IDs can be sent in the request body.

query Parameters
withCurrentGames
boolean
Default: false

Include the already started games at the beginning of the stream.

Request Body schema: text/plain
required

Up to 300 user IDs separated by commas. Example: aliquantus,chess-network,lovlas

string

Responses

Response samples

Content type
application/x-ndjson
[
  • {
    }
]

Stream games by IDs

Creates a stream of games from an arbitrary streamId, and a list of game IDs.

The stream first outputs the games that already exists, then emits an event each time a game is started or finished.

Games are streamed as ndjson.

Maximum number of games: 500 for anonymous requests, or 1000 for OAuth2 authenticated requests.

While the stream is open, it is possible to add new game IDs to watch.

path Parameters
streamId
required
string
Example: myAppName-someRandomId

Arbitrary stream ID that you can later use to add game IDs to the stream.

Request Body schema: text/plain
required

Up to 500 or 1000 game IDs separated by commas. Example: gameId01,gameId02,gameId03

string

Responses

Response samples

Content type
application/x-ndjson
[
  • {
    }
]

Add game IDs to stream

Add new game IDs for an existing stream to watch. The stream will immediately outputs the games that already exists, then emit an event each time a game is started or finished.

path Parameters
streamId
required
string
Example: myAppName-someRandomId

The stream ID you used to create the stream.

Request Body schema: text/plain
required

Up to 500 or 1000 game IDs separated by commas. Example: gameId04,gameId05,gameId06

string

Responses

Response samples

Content type
application/json
{
  • "ok": true
}

Get my ongoing games

Get the ongoing games of the current user. Real-time and correspondence games are included. The most urgent games are listed first.

Authorizations:
OAuth2
query Parameters
nb
integer [ 1 .. 50 ]
Default: 9

Max number of games to fetch

Responses

Response samples

Content type
application/json
{
  • "nowPlaying": [
    ]
}

Stream moves of a game

Stream positions and moves of any ongoing game, in ndjson.

A description of the game is sent as a first message. Then a message is sent each time a move is played. Finally a description of the game is sent when it finishes, and the stream is closed.

Ongoing games are delayed by a few seconds ranging from 3 to 60 depending on the time control, as to prevent cheat bots from using this API.

No more than 8 game streams can be opened at the same time from the same IP address.

path Parameters
id
required
string
Example: LuGQwhBb

Responses

Response samples

Content type
application/x-ndjson
[
  • {
    },
  • {
    },
  • {
    },
  • {
    },
  • {
    },
  • {
    }
]

Import one game

Import a game from PGN. See https://lichess.org/paste.

Rate limiting: 200 games per hour for OAuth requests, 100 games per hour for anonymous requests.

To broadcast ongoing games, consider pushing to a broadcast instead.

To analyse a position or a line, just construct an analysis board URL: https://lichess.org/analysis/pgn/e4_e5_Nf3_Nc6_Bc4_Bc5_Bxf7+

Authorizations:
OAuth2
Request Body schema: application/x-www-form-urlencoded
required

A single game to import

pgn
string

The PGN. It can contain only one game. Most standard tags are supported.

Responses

Response samples

Content type
application/json
{}

Export your imported games

Download all games imported by you. Games are exported in PGN format.

Authorizations:
OAuth2

Responses

TV

Access Lichess TV channels and games. https://lichess.org/tv & https://lichess.org/games

Get current TV games

Get basic info about the best games being played for each speed and variant, but also computer games and bot games.

See lichess.org/tv.

Responses

Response samples

Content type
application/json
{
  • "bot": {
    },
  • "blitz": {
    },
  • "racingKings": {
    },
  • "ultraBullet": {
    },
  • "bullet": {
    },
  • "classical": {
    },
  • "threeCheck": {
    },
  • "antichess": {
    },
  • "computer": {
    },
  • "horde": {
    },
  • "rapid": {
    },
  • "atomic": {
    },
  • "crazyhouse": {
    },
  • "chess960": {
    },
  • "kingOfTheHill": {
    },
  • "topRated": {
    }
}

Stream current TV game

Stream positions and moves of the current TV game in ndjson. A summary of the game is sent as a first message, and when the featured game changes.

Try it with curl https://lichess.org/api/tv/feed.

Responses

Response samples

Content type
application/x-ndjson
{
  • "t": "featured",
  • "d": {
    }
}

Get best ongoing games of a TV channel

Get a list of ongoing games for a given TV channel. Similar to lichess.org/games.

Available in PGN or ndjson format, depending on the request Accept header.

path Parameters
channel
required
string

The name of the channel in camel case.

query Parameters
nb
number [ 1 .. 30 ]
Default: 10

Number of games to fetch.

moves
boolean
Default: true

Include the PGN moves.

pgnInJson
boolean
Default: false

Include the full PGN within the JSON response, in a pgn field.

tags
boolean
Default: true

Include the PGN tags.

clocks
boolean
Default: false

Include clock status when available.

Either as PGN comments: 2. exd5 { [%clk 1:01:27] } e5 { [%clk 1:01:28] }

Or in a clocks JSON field, as centisecond integers, depending on the response type.

opening
boolean
Default: false

Include the opening name.

Example: [Opening "King's Gambit Accepted, King's Knight Gambit"]

Responses

Response samples

Content type
No sample

Puzzles

Access Lichess puzzle history and dashboard.

Our collection of puzzles is in the public domain, you can download it here. For a list of our puzzle themes with their description, check out the theme translation file. The daily puzzle can be posted in your slack workspace.

Get the daily puzzle

Get the daily Lichess puzzle in JSON format.

Alternatively, you can post it in your slack workspace.

Responses

Response samples

Content type
application/json
{
  • "game": {
    },
  • "puzzle": {
    }
}

Get a puzzle by its ID

Get a single Lichess puzzle in JSON format.

path Parameters
id
required
string

The puzzle ID

Responses

Response samples

Content type
application/json
{
  • "game": {
    },
  • "puzzle": {
    }
}

Get your puzzle activity

Download your puzzle activity in ndjson format.

Puzzle activity is sorted by reverse chronological order (most recent first)

We recommend streaming the response, for it can be very long.

Authorizations:
OAuth2
query Parameters
max
integer >= 1

How many entries to download. Leave empty to download all activity.

before
integer >= 1356998400070

Download entries before this timestamp. Defaults to now. Use before and max for pagination.

Responses

Response samples

Content type
application/x-ndjson
{
  • "date": 1514505150384,
  • "win": true,
  • "puzzle": {
    }
}

Get your puzzle dashboard

Download your puzzle dashboard as JSON.

Also includes all puzzle themes played, with aggregated results.

Allows re-creating the improvement/strengths interfaces.

Authorizations:
OAuth2
path Parameters
days
required
integer >= 1

How many days to look back when aggregating puzzle results. 30 is sensible.

Responses

Response samples

Content type
application/json
{
  • "days": 30,
  • "global": {
    },
  • "themes": {
    }
}

Get the storm dashboard of a player

Download the storm dashboard of any player as JSON.

Contains the aggregated highscores, and the history of storm runs aggregated by days.

Use ?days=0 if you only care about the highscores.

path Parameters
username
required
string

Username of the player

query Parameters
days
integer [ 0 .. 365 ]
Default: 30

How many days of history to return

Responses

Response samples

Content type
application/json
{
  • "high": {
    },
  • "days": [
    ]
}

Create and join a puzzle race

Create a new private puzzle race. The Lichess user who creates the race must join the race page, and manually start the race when enough players have joined.

Authorizations:
OAuth2

Responses

Response samples

Content type
application/json
{}

Teams

Access and manage Lichess teams and their members. https://lichess.org/team

Get team swiss tournaments

Get all swiss tournaments of a team.

Tournaments are sorted by reverse chronological order of start date (last starting first).

Tournaments are streamed as ndjson.

path Parameters
teamId
required
string
Example: coders
query Parameters
max
integer >= 1
Default: 100

How many tournaments to download.

Responses

Response samples

Content type
application/nd-json
{
  • "rated": true,
  • "clock": {
    },
  • "createdBy": "thibault",
  • "id": "ZmKWCOye",
  • "name": "Wang",
  • "nbOngoing": 0,
  • "nbPlayers": 0,
  • "nbRounds": 2,
  • "nextRound": {
    },
  • "round": 0,
  • "startsAt": "2020-05-11T12:23:18.233-06:00",
  • "status": "created",
  • "variant": "standard",
  • "isRecentlyFinished": false,
  • "password": true,
  • "stats": {
    }
}

Get a single team

Public info about a team. Includes the list of publicly visible leaders.

path Parameters
teamId
required
string

Responses

Response samples

Content type
application/json
{
  • "id": "coders",
  • "name": "Coders",
  • "description": "There are 10 kinds of people in the world: those who understand binary, and the others.\r\n\r\nIf you want to join the team, prove (briefly) that you can code in the request message!",
  • "open": false,
  • "leaders": [
    ],
  • "nbMembers": 3129
}

Get popular teams

Paginator of the most popular teams.

query Parameters
page
number
Default: 1
Example: page=1

Responses

Response samples

Content type
application/json
{
  • "currentPage": 4,
  • "maxPerPage": 15,
  • "currentPageResults": [
    ],
  • "nbResults": 205194,
  • "previousPage": 3,
  • "nextPage": 5,
  • "nbPages": 13680
}

Teams of a player

All the teams a player is a member of.

path Parameters
username
required
string
Example: thibault

Responses

Response samples

Content type
application/json
[
  • {
    }
]

Search teams

Paginator of team search results for a keyword.

query Parameters
text
string
Example: text=coders
page
number
Default: 1
Example: page=1

Responses

Response samples

Content type
application/json
{
  • "currentPage": 4,
  • "maxPerPage": 15,
  • "currentPageResults": [
    ],
  • "nbResults": 205194,
  • "previousPage": 3,
  • "nextPage": 5,
  • "nbPages": 13680
}

Get members of a team

Members are sorted by reverse chronological order of joining the team (most recent first). OAuth is only required if the list of members is private.

Members are streamed as ndjson.

Authorizations:
OAuth2
path Parameters
teamId
required
string
Example: coders

Responses

Response samples

Content type
application/x-ndjson
{
  • "id": "georges",
  • "username": "Georges",
  • "perfs": {
    },
  • "createdAt": 1290415680000,
  • "disabled": false,
  • "tosViolation": false,
  • "profile": {
    },
  • "seenAt": 1522636452014,
  • "patron": true,
  • "verified": true,
  • "playTime": {
    },
  • "title": "NM",
  • "count": {
    },
  • "streaming": false,
  • "streamer": {},
  • "followable": true,
  • "following": false,
  • "blocking": false,
  • "followsYou": false
}

Get team Arena tournaments

Get all Arena tournaments relevant to a team.

Tournaments are sorted by reverse chronological order of start date (last starting first).

Tournaments are streamed as ndjson.

path Parameters
teamId
required
string

ID of the team

query Parameters
max
integer >= 1
Default: 100

How many tournaments to download.

Responses

Response samples

Content type
application/x-ndjson
{
  • "id": "QITRjufu",
  • "createdBy": "lichess",
  • "system": "arena",
  • "minutes": 57,
  • "clock": {
    },
  • "rated": true,
  • "fullName": "U1700 SuperBlitz Arena",
  • "nbPlayers": 154,
  • "variant": {
    },
  • "startsAt": 1522803600000,
  • "finishesAt": 1522807200000,
  • "status": 30,
  • "perf": {
    },
  • "secondsToStart": 576,
  • "hasMaxRating": true,
  • "maxRating": {
    },
  • "minRating": {
    },
  • "minRatedGames": {
    },
  • "onlyTitled": false,
  • "teamMember": "coders",
  • "private": true,
  • "position": {},
  • "schedule": {
    },
  • "teamBattle": {
    },
  • "winner": {
    }
}

Join a team

Join a team. If the team requires a password but the password field is incorrect, then the call fails with 403 Forbidden. Similarly, if the team join policy requires a confirmation but the message parameter is not given, then the call fails with 403 Forbidden.

Authorizations:
OAuth2
path Parameters
teamId
required
string
Example: coders
Request Body schema: application/x-www-form-urlencoded
required
message
string

Optional request message, if the team requires one.

password
string

Optional password, if the team requires one.

Responses

Response samples

Content type
application/json
{
  • "ok": true
}

Leave a team

Authorizations:
OAuth2
path Parameters
teamId
required
string
Example: coders

Responses

Response samples

Content type
application/json
{
  • "ok": true
}

Get join requests

Get pending join requests of your team

Authorizations:
OAuth2
path Parameters
teamId
required
string
query Parameters
declined
boolean
Default: false

Get the declined join requests

Responses

Response samples

Content type
application/json
[
  • {
    }
]

Accept join request

Accept someone's request to join your team

Authorizations:
OAuth2
path Parameters
teamId
required
string
Example: coders
userId
required
string
Example: neio

Responses

Response samples

Content type
application/json
{
  • "ok": true
}

Decline join request

Decline someone's request to join your team

Authorizations:
OAuth2
path Parameters
teamId
required
string
Example: coders
userId
required
string
Example: neio

Responses

Response samples

Content type
application/json
{
  • "ok": true
}

Kick a user from your team

Kick a member out of one of your teams.

Authorizations:
OAuth2
path Parameters
teamId
required
string
Example: coders
userId
required
string
Example: neio

Responses

Response samples

Content type
application/json
{
  • "ok": true
}

Message all members

Send a private message to all members of a team. You must be a team leader with the "Messages" permission.

Authorizations:
OAuth2
path Parameters
teamId
required
string
Example: coders
Request Body schema: application/x-www-form-urlencoded
required
message
string

The message to send to all your team members.

Responses

Response samples

Content type
application/json
{
  • "ok": true
}

Board

Play on Lichess with physical boards and third-party clients. Works with normal Lichess accounts. Engine play or assistance is forbidden.

Features

Restrictions

Stream incoming events

Stream the events reaching a lichess user in real time as ndjson.

An empty line is sent every 6 seconds for keep alive purposes.

Each non-empty line is a JSON object containing a type field. Possible values are:

  • gameStart Start of a game
  • gameFinish Completion of a game
  • challenge A player sends you a challenge or you challenge someone
  • challengeCanceled A player cancels their challenge to you
  • challengeDeclined The opponent declines your challenge

When the stream opens, all current challenges and games are sent.

Authorizations:
OAuth2

Responses

Response samples

Content type
application/x-ndjson
Example
{
  • "type": "challenge",
  • "challenge": {
    }
}

Create a seek

Create a public seek, to start a game with a random player.

Real-time seek

Specify the time and increment clock values. The response is streamed but doesn't contain any information.

Keep the connection open to keep the seek active.

If the client closes the connection, the seek is canceled. This way, if the client terminates, the user won't be paired in a game they wouldn't play. When the seek is accepted, or expires, the server closes the connection.

Make sure to also have an Event stream open, to be notified when a game starts. We recommend opening the Event stream first, then the seek stream. This way, you won't miss the game event if the seek is accepted immediately.

Correspondence seek

Specify the days per turn value. The response is not streamed, it immediately completes with the seek ID. The seek remains active on the server until it is joined by someone.

Authorizations:
OAuth2
Request Body schema: application/x-www-form-urlencoded
required

Parameters of the seek

rated
boolean
Default: false

Whether the game is rated and impacts players ratings.

time
number [ 0 .. 180 ]

Clock initial time in minutes. Required for real-time seeks.

increment
integer [ 0 .. 180 ]

Clock increment in seconds. Required for real-time seeks.

days
integer
Enum: 1 2 3 5 7 10 14

Days per turn. Required for correspondence seeks.

variant
string (VariantKey)
Enum: "standard" "chess960" "crazyhouse" "antichess" "atomic" "horde" "kingOfTheHill" "racingKings" "threeCheck" "fromPosition"
color
string
Default: "random"
Enum: "random" "white" "black"

The color to play. Better left empty to automatically get 50% white.

ratingRange
string

The rating range of potential opponents. Better left empty. Example: 1500-1800

Responses

Response samples

Content type
text/plain

Stream Board game state

Stream the state of a game being played with the Board API, as ndjson.

Use this endpoint to get updates about the game in real-time, with a single request.

Each line is a JSON object containing a type field. Possible values are:

  • gameFull Full game data. All values are immutable, except for the state field.

  • gameState Current state of the game. Immutable values not included. Sent when a move is played, a draw is offered, or when the game ends.

  • chatLine Chat message sent by a user in the room "player" or "spectator".

  • opponentGone Whether the opponent has left the game, and how long before you can claim a win or draw.

The first line is always of type gameFull.

The server closes the stream when the game ends, or if the game has already ended.

Authorizations:
OAuth2
path Parameters
gameId
required
string
Example: 5IrD6Gzz

Responses

Response samples

Content type
application/x-ndjson
Example
{
  • "type": "gameFull",
  • "id": "5IrD6Gzz",
  • "rated": true,
  • "variant": {
    },
  • "clock": {
    },
  • "speed": "classical",
  • "perf": {
    },
  • "createdAt": 1523825103562,
  • "white": {
    },
  • "black": {
    },
  • "initialFen": "startpos",
  • "state": {
    }
}

Make a Board move

Make a move in a game being played with the Board API.

The move can also contain a draw offer/agreement.

Authorizations:
OAuth2
path Parameters
gameId
required
string
Example: 5IrD6Gzz
move
required
string
Example: e2e4

The move to play, in UCI format

query Parameters
offeringDraw
boolean

Whether to offer (or agree to) a draw

Responses

Response samples

Content type
application/json
{
  • "ok": true
}

Write in the chat

Post a message to the player or spectator chat, in a game being played with the Board API.

Authorizations:
OAuth2
path Parameters
gameId
required
string
Example: 5IrD6Gzz
Request Body schema: application/x-www-form-urlencoded
required
room
required
string
Enum: "player" "spectator"
text
required
string

Responses

Response samples

Content type
application/json
{
  • "ok": true
}

Fetch the game chat

Get the messages posted in the game chat

Authorizations:
OAuth2
path Parameters
gameId
required
string
Example: 5IrD6Gzz

Responses

Response samples

Content type
application/x-ndjson
[
  • {
    },
  • {
    },
  • {
    }
]

Abort a game

Abort a game being played with the Board API.

Authorizations:
OAuth2
path Parameters
gameId
required
string
Example: 5IrD6Gzz

Responses

Response samples

Content type
application/json
{
  • "ok": true
}

Resign a game

Resign a game being played with the Board API.

Authorizations:
OAuth2
path Parameters
gameId
required
string
Example: 5IrD6Gzz

Responses

Response samples

Content type
application/json
{
  • "ok": true
}

Handle draw offers

Create/accept/decline draw offers.

  • yes: Offer a draw, or accept the opponent's draw offer.
  • no: Decline a draw offer from the opponent.
Authorizations:
OAuth2
path Parameters
gameId
required
string
Example: 5IrD6Gzz
required
boolean or "yes" (string)
Example: yes

Responses

Response samples

Content type
application/json
{
  • "ok": true
}

Handle takeback offers

Create/accept/decline takebacks.

  • yes: Propose a takeback, or accept the opponent's takeback offer.
  • no: Decline a takeback offer from the opponent.
Authorizations:
OAuth2
path Parameters
gameId
required
string
Example: 5IrD6Gzz
required
boolean or "yes" (string)
Example: yes

Responses

Response samples

Content type
application/json
{
  • "ok": true
}

Claim victory of a game

Claim victory when the opponent has left the game for a while.

Authorizations:
OAuth2
path Parameters
gameId
required
string
Example: 5IrD6Gzz

Responses

Response samples

Content type
application/json
{
  • "ok": true
}

Berserk a tournament game

Go berserk on an arena tournament game. Halves the clock time, grants an extra point upon winning. Only available in arena tournaments that allow berserk, and before each player has made a move.

Authorizations:
OAuth2
path Parameters
gameId
required
string
Example: 5IrD6Gzz

Responses

Response samples

Content type
application/json
{
  • "ok": true
}

Bot

Play on Lichess as a bot. Allows engine play. Read the blog post announcement of lichess bots.

Only works with Bot accounts.

Features

Restrictions

  • Bots can only play challenge games: pools and tournaments are off-limits
  • Bots cannot play UltraBullet (¼+0) because it requires making too many requests. But 0+1 and ½+0 are allowed.
  • Bots must follow Lichess TOS specifically Sandbagging, Constant Aborting, Boosting, etc
  • Bot devs are advised to make their Bots play casual only when testing their Bots logic and to avoid breaking Lichess TOS.

Integrations

Stream incoming events

Stream the events reaching a lichess user in real time as ndjson.

An empty line is sent every 6 seconds for keep alive purposes.

Each non-empty line is a JSON object containing a type field. Possible values are:

  • gameStart Start of a game
  • gameFinish Completion of a game
  • challenge A player sends you a challenge or you challenge someone
  • challengeCanceled A player cancels their challenge to you
  • challengeDeclined The opponent declines your challenge

When the stream opens, all current challenges and games are sent.

Authorizations:
OAuth2

Responses

Response samples

Content type
application/x-ndjson
Example
{
  • "type": "challenge",
  • "challenge": {
    }
}

Get online bots

Stream the online bot users, as ndjson. Throttled to 50 bot users per second.

query Parameters
nb
integer >= 1
Example: nb=20

How many bot users to fetch

Responses

Response samples

Content type
application/x-ndjson
{
  • "id": "georges",
  • "username": "Georges",
  • "perfs": {
    },
  • "createdAt": 1290415680000,
  • "disabled": false,
  • "tosViolation": false,
  • "profile": {
    },
  • "seenAt": 1522636452014,
  • "patron": true,
  • "verified": true,
  • "playTime": {
    },
  • "title": "NM"
}

Upgrade to Bot account

Upgrade a lichess player account into a Bot account. Only Bot accounts can use the Bot API.

The account cannot have played any game before becoming a Bot account. The upgrade is irreversible. The account will only be able to play as a Bot.

To upgrade an account to Bot, use the official lichess-bot client, or follow these steps:

  • Create an API access token with "Play bot moves" permission.
  • curl -d '' https://lichess.org/api/bot/account/upgrade -H "Authorization: Bearer <yourTokenHere>"

To know if an account has already been upgraded, use the Get my profile API: the title field should be set to BOT.

Authorizations:
OAuth2

Responses

Response samples

Content type
application/json
{
  • "ok": true
}

Stream Bot game state

Stream the state of a game being played with the Bot API, as ndjson.

Use this endpoint to get updates about the game in real-time, with a single request.

Each line is a JSON object containing a type field. Possible values are:

  • gameFull Full game data. All values are immutable, except for the state field.

  • gameState Current state of the game. Immutable values not included.

  • chatLine Chat message sent by a user (or the bot itself) in the room "player" or "spectator".

  • opponentGone Whether the opponent has left the game, and how long before you can claim a win or draw.

The first line is always of type gameFull.

Authorizations:
OAuth2
path Parameters
gameId
required
string
Example: 5IrD6Gzz

Responses

Response samples

Content type
application/x-ndjson
Example
{
  • "type": "gameFull",
  • "id": "5IrD6Gzz",
  • "rated": true,
  • "variant": {
    },
  • "clock": {
    },
  • "speed": "classical",
  • "perf": {
    },
  • "createdAt": 1523825103562,
  • "white": {
    },
  • "black": {
    },
  • "initialFen": "startpos",
  • "state": {
    }
}

Make a Bot move

Make a move in a game being played with the Bot API.

The move can also contain a draw offer/agreement.

Authorizations:
OAuth2
path Parameters
gameId
required
string
Example: 5IrD6Gzz
move
required
string
Example: e2e4

The move to play, in UCI format

query Parameters
offeringDraw
boolean

Whether to offer (or agree to) a draw

Responses

Response samples

Content type
application/json
{
  • "ok": true
}

Write in the chat

Post a message to the player or spectator chat, in a game being played with the Bot API.

Authorizations:
OAuth2
path Parameters
gameId
required
string
Example: 5IrD6Gzz
Request Body schema: application/x-www-form-urlencoded
required
room
required
string
Enum: "player" "spectator"
text
required
string

Responses

Response samples

Content type
application/json
{
  • "ok": true
}

Fetch the game chat

Get the messages posted in the game chat

Authorizations:
OAuth2
path Parameters
gameId
required
string
Example: 5IrD6Gzz

Responses

Response samples

Content type
application/x-ndjson
[
  • {
    },
  • {
    },
  • {
    }
]

Abort a game

Abort a game being played with the Bot API.

Authorizations:
OAuth2
path Parameters
gameId
required
string
Example: 5IrD6Gzz

Responses

Response samples

Content type
application/json
{
  • "ok": true
}

Resign a game

Resign a game being played with the Bot API.

Authorizations:
OAuth2
path Parameters
gameId
required
string
Example: 5IrD6Gzz

Responses

Response samples

Content type
application/json
{
  • "ok": true
}

Handle draw offers in bot games

Create/accept/decline draw offers in bot games

  • yes: Offer a draw, or accept the opponent's draw offer.
  • no: Decline a draw offer from the opponent.
Authorizations:
OAuth2
path Parameters
gameId
required
string
Example: 5IrD6Gzz
required
boolean or "yes" (string)
Example: yes

Responses

Response samples

Content type
application/json
{
  • "ok": true
}

Challenges

Send and receive challenges to play.

To create a lot of challenges, consider bulk pairing instead.

List your challenges

Get a list of challenges created by or targeted at you.

Authorizations:
OAuth2

Responses

Response samples

Content type
application/json
{
  • "in": [
    ],
  • "out": [
    ]
}

Create a challenge

Challenge someone to play. The targeted player can choose to accept or decline.

If the challenge is accepted, you will be notified on the event stream that a new game has started. The game ID will be the same as the challenge ID.

Challenges for realtime games (not correspondence) expire after 20s if not accepted. To prevent that, use the keepAliveStream flag described below.

Authorizations:
OAuth2
path Parameters
username
required
string
Example: LeelaChess
Request Body schema: application/x-www-form-urlencoded
required

Parameters of the challenge

rated
boolean
Default: false

Game is rated and impacts players ratings

clock.limit
number [ 0 .. 10800 ]

Clock initial time in seconds. If empty, a correspondence game is created. Valid values are 0, 15, 30, 45, 60, 90, and any multiple of 60 up to 10800 (3 hours).

clock.increment
integer [ 0 .. 60 ]

Clock increment in seconds. If empty, a correspondence game is created.

days
integer
Enum: 1 2 3 5 7 10 14

Days per move, for correspondence games. Clock settings must be omitted.

color
string
Default: "random"
Enum: "random" "white" "black"

Which color you get to play

variant
string (VariantKey)
Enum: "standard" "chess960" "crazyhouse" "antichess" "atomic" "horde" "kingOfTheHill" "racingKings" "threeCheck" "fromPosition"
fen
string (FromPositionFEN)

Custom initial position (in FEN). Variant must be standard, fromPosition, or chess960 (if a valid 960 starting position), and the game cannot be rated.

keepAliveStream
boolean

If set, the response is streamed as ndjson. The challenge is kept alive until the connection is closed by the client. When the challenge is accepted, declined or canceled, a message of the form {"done":"accepted"} is sent, then the connection is closed by the server. If not set, the response is not streamed, and the challenge expires after 20s if not accepted.

rules
string
Enum: "noAbort" "noRematch" "noGiveTime" "noClaimWin" "noEarlyDraw"

Extra game rules separated by commas. Example: noAbort,noRematch

Responses

Response samples

Content type
application/json
{
  • "challenge": {
    }
}

Accept a challenge

Accept an incoming challenge.

You should receive a gameStart event on the incoming events stream.

Authorizations:
OAuth2
path Parameters
challengeId
required
string
Example: 5IrD6Gzz

Responses

Response samples

Content type
application/json
{
  • "ok": true
}

Decline a challenge

Decline an incoming challenge.

Authorizations:
OAuth2
path Parameters
challengeId
required
string
Example: 5IrD6Gzz
Request Body schema: application/x-www-form-urlencoded
optional

Details related to decline of challenge

reason
string
Enum: "generic" "later" "tooFast" "tooSlow" "timeControl" "rated" "casual" "standard" "variant" "noBot" "onlyBot"

Reason challenge was declined. It will be translated to the player's language. See the full list in the translation file.

Responses

Response samples

Content type
application/json
{
  • "ok": true
}

Cancel a challenge

Cancel a challenge you sent, or aborts the game if the challenge was accepted, but the game was not yet played. Note that the ID of a game is the same as the ID of the challenge that created it.

Works for user challenges and open challenges alike.

Authorizations:
OAuth2
path Parameters
challengeId
required
string
Example: 5IrD6Gzz
query Parameters
opponentToken
string

Optional challenge:write token of the opponent. If set, the game can be canceled even if both players have moved.

Responses

Response samples

Content type
application/json
{
  • "ok": true
}

Challenge the AI

Start a game with Lichess AI.

You will be notified on the event stream that a new game has started.

Authorizations:
OAuth2
Request Body schema: application/x-www-form-urlencoded
required

Parameters of the game

level
number [ 1 .. 8 ]

AI strength

clock.limit
number [ 0 .. 10800 ]

Clock initial time in seconds. If empty, a correspondence game is created.

clock.increment
integer [ 0 .. 60 ]

Clock increment in seconds. If empty, a correspondence game is created.

days
integer
Enum: 1 2 3 5 7 10 14

Days per move, for correspondence games. Clock settings must be omitted.

color
string
Default: "random"
Enum: "random" "white" "black"

Which color you get to play

variant
string (VariantKey)
Enum: "standard" "chess960" "crazyhouse" "antichess" "atomic" "horde" "kingOfTheHill" "racingKings" "threeCheck" "fromPosition"
fen
string (FromPositionFEN)

Custom initial position (in FEN). Variant must be standard, fromPosition, or chess960 (if a valid 960 starting position), and the game cannot be rated.

Responses

Response samples

Content type
application/json
{
  • "id": "q7ZvsdUF",
  • "rated": true,
  • "variant": "standard",
  • "speed": "blitz",
  • "perf": "blitz",
  • "createdAt": 1514505150384,
  • "lastMoveAt": 1514505592843,
  • "status": "draw",
  • "players": {
    },
  • "opening": {
    },
  • "moves": "d4 d5 c4 c6 Nc3 e6 e4 Nd7 exd5 cxd5 cxd5 exd5 Nxd5 Nb6 Bb5+ Bd7 Qe2+ Ne7 Nxb6 Qxb6 Bxd7+ Kxd7 Nf3 Qa6 Ne5+ Ke8 Qf3 f6 Nd3 Qc6 Qe2 Kf7 O-O Kg8 Bd2 Re8 Rac1 Nf5 Be3 Qe6 Rfe1 g6 b3 Bd6 Qd2 Kf7 Bf4 Qd7 Bxd6 Nxd6 Nc5 Rxe1+ Rxe1 Qc6 f3 Re8 Rxe8 Nxe8 Kf2 Nc7 Qb4 b6 Qc4+ Nd5 Nd3 Qe6 Nb4 Ne7 Qxe6+ Kxe6 Ke3 Kd6 g3 h6 Kd3 h5 Nc2 Kd5 a3 Nc6 Ne3+ Kd6 h4 Nd8 g4 Ne6 Ke4 Ng7 Nc4+ Ke6 d5+ Kd7 a4 g5 gxh5 Nxh5 hxg5 fxg5 Kf5 Nf4 Ne3 Nh3 Kg4 Ng1 Nc4 Kc7 Nd2 Kd6 Kxg5 Kxd5 f4 Nh3+ Kg4 Nf2+ Kf3 Nd3 Ke3 Nc5 Kf3 Ke6 Ke3 Kf5 Kd4 Ne6+ Kc4",
  • "clock": {
    }
}

Open-ended challenge

Create a challenge that any 2 players can join.

Share the URL of the challenge. the first 2 players to click it will be paired for a game.

The response body also contains whiteUrl and blackUrl. You can control which color each player gets by giving them these URLs, instead of the main challenge URL.

Open challenges expire after 24h.

If the challenge creation is authenticated with OAuth2, then you can use the challenge cancel endpoint to cancel it.

To directly pair 2 known players, use this endpoint instead.

Request Body schema: application/x-www-form-urlencoded
required

Parameters of the game

rated
boolean
Default: false

Game is rated and impacts players ratings

clock.limit
number [ 0 .. 10800 ]

Clock initial time in seconds. If empty, a correspondence game is created.

clock.increment
integer [ 0 .. 60 ]

Clock increment in seconds. If empty, a correspondence game is created.

days
integer
Enum: 1 2 3 5 7 10 14

Days per turn. For correspondence challenges.

variant
string (VariantKey)
Enum: "standard" "chess960" "crazyhouse" "antichess" "atomic" "horde" "kingOfTheHill" "racingKings" "threeCheck" "fromPosition"
fen
string (FromPositionFEN)

Custom initial position (in FEN). Variant must be standard, fromPosition, or chess960 (if a valid 960 starting position), and the game cannot be rated.

name
string

Optional name for the challenge, that players will see on the challenge page.

rules
string
Enum: "noRematch" "noGiveTime" "noClaimWin" "noEarlyDraw" "noAbort"

Extra game rules separated by commas. Example: noRematch,noGiveTime The noAbort rule is available for Lichess admins only

users
string

Optional pair of usernames, separated by a comma. If set, only these users will be allowed to join the game. The first username gets the white pieces. Example: Username1,Username2

expiresAt
integer

Timestamp in milliseconds to expire the challenge. Defaults to 24h after creation. Can't be more than 2 weeks after creation.

Responses

Response samples

Content type
application/json
{
  • "id": "VU0nyvsW",
  • "color": "random",
  • "direction": "out",
  • "timeControl": {
    },
  • "variant": {
    },
  • "challenger": {
    },
  • "destUser": {
    },
  • "perf": {
    },
  • "rated": true,
  • "speed": "blitz",
  • "status": "created"
}

Start clocks of a game

Start the clocks of a game immediately, even if a player has not yet made a move.

Requires the OAuth tokens of both players with challenge:write scope.

If the clocks have already started, the call will have no effect.

Authorizations:
OAuth2
path Parameters
gameId
required
string

ID of the game

query Parameters
token1
string

OAuth token of a player

token2
string

OAuth token of the other player

Responses

Response samples

Content type
application/json
{
  • "ok": true
}

Add time to the opponent clock

Add seconds to the opponent's clock. Can be used to create games with time odds.

Authorizations:
OAuth2
path Parameters
gameId
required
string

ID of the game

seconds
required
string [ 1 .. 86400 ]

How many seconds to give

Responses

Response samples

Content type
application/json
{
  • "ok": true
}

Admin challenge tokens

This endpoint can only be used by Lichess administrators. It will not work if you do not have the appropriate permissions. Tournament organizers should instead use OAuth to obtain challenge:write tokens from users in order to perform bulk pairing.*

Create and obtain challenge:write tokens for multiple users.

If a similar token already exists for a user, it is reused. This endpoint is idempotent.

Authorizations:
OAuth2
Request Body schema: application/x-www-form-urlencoded
required
users
required
string

Usernames separated with commas

description
required
string

User visible description of the token

Responses

Response samples

Content type
application/json
{
  • "thibault": "lLOEkpH58W599xH9",
  • "neio": "nAYTIJphwWFwKmKk",
  • "lizen2": "1cnHhuWKHROgiPC4",
  • "lizen3": "SszJ9Sj1bto0UQCK"
}

Bulk pairings

Create many games for other players.

These endpoints are intended for tournament organisers.

View your bulk pairings

Get a list of bulk pairings you created.

Authorizations:
OAuth2

Responses

Response samples

Content type
application/json
[
  • {
    }
]

Create a bulk pairing

Schedule many games at once, up to 24h in advance.

OAuth tokens are required for all paired players, with the challenge:write scope.

You can schedule up to 500 games every 10 minutes. Contact us if you need higher limits.

If games have a real-time clock, each player must have only one pairing. For correspondence games, players can have multiple pairings within the same bulk.

The entire bulk is rejected if:

  • a token is missing
  • a token is present more than once (except in correspondence)
  • a token lacks the challenge:write scope
  • a player account is closed
  • a player is paired more than once (except in correspondence)
  • a bulk is already scheduled to start at the same time with the same player
  • you have 20 scheduled bulks
  • you have 1000 scheduled games

Partial bulks are never created. Either it all fails, or it all succeeds. When it fails, it does so with an error message explaining the issue. Failed bulks are not counted in the rate limiting, they are free. Fix the issues, manually or programmatically, then retry to schedule the bulk.

A successful bulk creation returns a JSON bulk document. Its ID can be used for further operations.

Authorizations:
OAuth2
Request Body schema: application/x-www-form-urlencoded
required

Parameters of the pairings

players
string

OAuth tokens of all the players to pair, with the syntax tokenOfWhitePlayerInGame1:tokenOfBlackPlayerInGame1,tokenOfWhitePlayerInGame2:tokenOfBlackPlayerInGame2,....

The 2 tokens of the players of a game are separated with :. The first token gets the white pieces. Games are separated with ,.

Up to 1000 tokens can be sent, for a max of 500 games.

Each token must be included at most once.

Example: token1:token2,token3:token4,token5:token6

clock.limit
number [ 0 .. 10800 ]

Clock initial time in seconds. Example: 600

clock.increment
integer [ 0 .. 60 ]

Clock increment in seconds. Example: 2

days
integer
Enum: 1 2 3 5 7 10 14

Days per turn. For correspondence games only.

pairAt
integer

Date at which the games will be created as a Unix timestamp in milliseconds. Up to 7 days in the future. Omit, or set to current date and time, to start the games immediately. Example: 1612289869919

startClocksAt
integer

Date at which the clocks will be automatically started as a Unix timestamp in milliseconds. Up to 7 days in the future. Note that the clocks can start earlier than specified, if players start making moves in the game. If omitted, the clocks will not start automatically. Example: 1612289869919

rated
boolean
Default: false

Game is rated and impacts players ratings

variant
string (VariantKey)
Enum: "standard" "chess960" "crazyhouse" "antichess" "atomic" "horde" "kingOfTheHill" "racingKings" "threeCheck" "fromPosition"
fen
string (FromPositionFEN)

Custom initial position (in FEN). Variant must be standard, fromPosition, or chess960 (if a valid 960 starting position), and the game cannot be rated.

message
string
Default: "Your game with {opponent} is ready: {game}."

Message that will be sent to each player, when the game is created. It is sent from your user account.

{opponent} and {game} are placeholders that will be replaced with the opponent and the game URLs.

You can omit this field to send the default message, but if you set your own message, it must at least contain the {game} placeholder.

rules
string
Enum: "noAbort" "noRematch" "noGiveTime" "noClaimWin" "noEarlyDraw"

Extra game rules separated by commas. Example: noAbort,noRematch

Responses

Response samples

Content type
application/json
{
  • "id": "RVAcwgg7",
  • "games": [
    ],
  • "variant": "standard",
  • "clock": {
    },
  • "pairAt": 1612289869919,
  • "pairedAt": null,
  • "rated": false,
  • "startClocksAt": 1612200422971,
  • "scheduledAt": 1612203514628
}

Manually start clocks

Immediately start all clocks of the games of a bulk pairing.

This overrides the startClocksAt value of an existing bulk pairing.

If the games have not yet been created (bulk.pairAt is in the future), then this does nothing.

If the clocks have already started (bulk.startClocksAt is in the past), then this does nothing.

Authorizations:
OAuth2
path Parameters
id
required
string
Example: 5IrD6Gzz

The ID of the bulk pairing

Responses

Response samples

Content type
application/json
{
  • "ok": true
}

Show a bulk pairing

Get a single bulk pairing by its ID.

Authorizations:
OAuth2
path Parameters
id
required
string
Example: 5IrD6Gzz

The ID of the bulk pairing

Responses

Response samples

Content type
application/json
{
  • "id": "RVAcwgg7",
  • "games": [
    ],
  • "variant": "standard",
  • "clock": {
    },
  • "pairAt": 1612289869919,
  • "pairedAt": null,
  • "rated": false,
  • "startClocksAt": 1612200422971,
  • "scheduledAt": 1612203514628
}

Cancel a bulk pairing

Cancel and delete a bulk pairing that is scheduled in the future.

If the games have already been created, then this does nothing.

Canceling a bulk pairing does not refund the rate limit cost of that bulk pairing.

Authorizations:
OAuth2
path Parameters
id
required
string
Example: 5IrD6Gzz

The ID of the bulk pairing

Responses

Response samples

Content type
application/json
{
  • "ok": true
}

Arena tournaments

Access Arena tournaments played on Lichess. Official Arena tournaments are maintained by Lichess, but you can create your own Arena tournaments as well.

Get current tournaments

Get recently finished, ongoing, and upcoming tournaments.

This API is used to display the Lichess tournament schedule.

Responses

Response samples

Content type
application/json
{
  • "created": [
    ],
  • "started": [
    ],
  • "finished": [
    ]
}

Create a new Arena tournament

Create a public or private Arena tournament.

This endpoint mirrors the form on https://lichess.org/tournament/new.

You can create up to 12 public tournaments per day, or 24 private tournaments.

A team battle can be created by specifying the teamBattleByTeam argument.

Additional restrictions:

  • clockTime + clockIncrement > 0
  • 15s and 0+1 variant tournaments cannot be rated
  • Clock time in comparison to tournament length must be reasonable: 3 <= (minutes * 60) / (96 * clockTime + 48 * clockIncrement + 15) <= 150
Authorizations:
OAuth2
Request Body schema: application/x-www-form-urlencoded
required

Parameters of the tournament

name
string [ 2 .. 30 ] characters

The tournament name. Leave empty to get a random Grandmaster name

clockTime
required
number
Enum: 0 0.25 0.5 0.75 1 1.5 2 3 4 5 6 7 8 10 15 20 25 30 40 50 60

Clock initial time in minutes

clockIncrement
required
integer
Enum: 0 1 2 3 4 5 6 7 10 15 20 25 30 40 50 60

Clock increment in seconds

minutes
required
integer
Enum: 20 25 30 35 40 45 50 55 60 70 80 90 100 110 120 150 180 210 240 270 300 330 360 420 480 540 600 720

How long the tournament lasts, in minutes

waitMinutes
integer
Default: 5
Enum: 1 2 3 5 10 15 20 30 45 60

How long to wait before starting the tournament, from now, in minutes

startDate
integer

Timestamp (in milliseconds) to start the tournament at a given date and time. Overrides the waitMinutes setting

variant
string (VariantKey)
Enum: "standard" "chess960" "crazyhouse" "antichess" "atomic" "horde" "kingOfTheHill" "racingKings" "threeCheck" "fromPosition"
rated
boolean
Default: true

Games are rated and impact players ratings

position
string (FromPositionFEN)

Custom initial position (in FEN). Variant must be standard, fromPosition, or chess960 (if a valid 960 starting position), and the game cannot be rated.

berserkable
boolean
Default: true

Whether the players can use berserk. Only allowed if clockIncrement <= clockTime * 2

streakable
boolean
Default: true

After 2 wins, consecutive wins grant 4 points instead of 2.

hasChat
boolean
Default: true

Whether the players can discuss in a chat

description
string

Anything you want to tell players about the tournament

password
string

Make the tournament private, and restrict access with a password. You can also generate user-specific entry codes based on this password.

teamBattleByTeam
string

Set the ID of a team you lead to create a team battle. The other teams can be added using the team battle edit endpoint.

conditions.teamMember.teamId
string

Restrict entry to members of a team.

The teamId is the last part of a team URL, e.g. https://lichess.org/team/coders has teamId = coders.

Leave empty to let everyone join the tournament.

Do not use this to create team battles, use teamBattleByTeam instead.

conditions.minRating.rating
integer
Enum: 1000 1100 1200 1300 1400 1500 1600 1700 1800 1900 2000 2100 2200 2300 2400 2500 2600

Minimum rating to join. Leave empty to let everyone join the tournament.

conditions.maxRating.rating
integer
Enum: 2200 2100 2000 1900 1800 1700 1600 1500 1400 1300 1200 1100 1000 900 800

Maximum rating to join. Based on best rating reached in the last 7 days. Leave empty to let everyone join the tournament.

conditions.nbRatedGame.nb
integer
Enum: 0 5 10 15 20 30 40 50 75 100 150 200

Minimum number of rated games required to join.

conditions.allowList
string

Predefined list of usernames that are allowed to join, separated by commas. If this list is non-empty, then usernames absent from this list will be forbidden to join. Adding %titled to the list additionally allows any titled player to join. Example: thibault,german11,%titled

Responses

Response samples

Content type
application/json
{
  • "id": "QITRjufu",
  • "fullName": "U1700 SuperBlitz Arena",
  • "rated": true,
  • "clock": {
    },
  • "minutes": 57,
  • "createdBy": "lichess",
  • "system": "arena",
  • "secondsToStart": 0,
  • "secondsToFinish": 36000,
  • "isFinished": true,
  • "isRecentlyFinished": true,
  • "pairingsClosed": true,
  • "startsAt": 1522803600000,
  • "nbPlayers": 154,
  • "perf": {
    },
  • "schedule": {
    },
  • "variant": "standard",
  • "duels": [
    ],
  • "standings": {
    },
  • "featured": {
    },
  • "podium": [
    ],
  • "stats": {
    }
}

Get info about an Arena tournament

Get detailed info about recently finished, current, or upcoming tournament's duels, player standings, and other info.

path Parameters
id
required
string

The tournament ID.

query Parameters
page
number [ 1 .. 200 ]
Default: 1
Example: page=1

Specify which page of player standings to view.

Responses

Response samples

Content type
application/json
{
  • "id": "QITRjufu",
  • "fullName": "U1700 SuperBlitz Arena",
  • "rated": true,
  • "clock": {
    },
  • "minutes": 57,
  • "createdBy": "lichess",
  • "system": "arena",
  • "secondsToStart": 0,
  • "secondsToFinish": 36000,
  • "isFinished": true,
  • "isRecentlyFinished": true,
  • "pairingsClosed": true,
  • "startsAt": 1522803600000,
  • "nbPlayers": 154,
  • "perf": {
    },
  • "schedule": {
    },
  • "variant": "standard",
  • "duels": [
    ],
  • "standings": {
    },
  • "featured": {
    },
  • "podium": [
    ],
  • "stats": {
    }
}

Update an Arena tournament

Update an Arena tournament.

Be mindful not to make important changes to ongoing tournaments.

Can be used to update a team battle.

Additional restrictions:

  • clockTime + clockIncrement > 0
  • 15s and 0+1 variant tournaments cannot be rated
  • Clock time in comparison to tournament length must be reasonable: 3 <= (minutes * 60) / (96 * clockTime + 48 * clockIncrement + 15) <= 150
Authorizations:
OAuth2
path Parameters
id
required
string

The tournament ID.

Request Body schema: application/x-www-form-urlencoded
required

Parameters of the tournament

name
string [ 2 .. 30 ] characters

The tournament name. Leave empty to get a random Grandmaster name

clockTime
required
number
Enum: 0 0.25 0.5 0.75 1 1.5 2 3 4 5 6 7 8 10 15 20 25 30 40 50 60

Clock initial time in minutes

clockIncrement
required
integer
Enum: 0 1 2 3 4 5 6 7 10 15 20 25 30 40 50 60

Clock increment in seconds

minutes
required
integer
Enum: 20 25 30 35 40 45 50 55 60 70 80 90 100 110 120 150 180 210 240 270 300 330 360 420 480 540 600 720

How long the tournament lasts, in minutes

waitMinutes
integer
Default: 5
Enum: 1 2 3 5 10 15 20 30 45 60

How long to wait before starting the tournament, from now, in minutes

startDate
integer

Timestamp (in milliseconds) to start the tournament at a given date and time. Overrides the waitMinutes setting

variant
string (VariantKey)
Enum: "standard" "chess960" "crazyhouse" "antichess" "atomic" "horde" "kingOfTheHill" "racingKings" "threeCheck" "fromPosition"
rated
boolean
Default: true

Games are rated and impact players ratings

position
string (FromPositionFEN)

Custom initial position (in FEN). Variant must be standard, fromPosition, or chess960 (if a valid 960 starting position), and the game cannot be rated.

berserkable
boolean
Default: true

Whether the players can use berserk. Only allowed if clockIncrement <= clockTime * 2

streakable
boolean
Default: true

After 2 wins, consecutive wins grant 4 points instead of 2.

hasChat
boolean
Default: true

Whether the players can discuss in a chat

description
string

Anything you want to tell players about the tournament

password
string

Make the tournament private, and restrict access with a password

conditions.minRating.rating
integer
Enum: 1000 1100 1200 1300 1400 1500 1600 1700 1800 1900 2000 2100 2200 2300 2400 2500 2600

Minimum rating to join. Leave empty to let everyone join the tournament.

conditions.maxRating.rating
integer
Enum: 2200 2100 2000 1900 1800 1700 1600 1500 1400 1300 1200 1100 1000 900 800

Maximum rating to join. Based on best rating reached in the last 7 days. Leave empty to let everyone join the tournament.

conditions.nbRatedGame.nb
integer
Enum: 0 5 10 15 20 30 40 50 75 100 150 200

Minimum number of rated games required to join.

conditions.allowList
string

Predefined list of usernames that are allowed to join, separated by commas. If this list is non-empty, then usernames absent from this list will be forbidden to join. Adding %titled to the list additionally allows any titled player to join. Example: thibault,german11,%titled

Responses

Response samples

Content type
application/json
{
  • "id": "QITRjufu",
  • "fullName": "U1700 SuperBlitz Arena",
  • "rated": true,
  • "clock": {
    },
  • "minutes": 57,
  • "createdBy": "lichess",
  • "system": "arena",
  • "secondsToStart": 0,
  • "secondsToFinish": 36000,
  • "isFinished": true,
  • "isRecentlyFinished": true,
  • "pairingsClosed": true,
  • "startsAt": 1522803600000,
  • "nbPlayers": 154,
  • "perf": {
    },
  • "schedule": {
    },
  • "variant": "standard",
  • "duels": [
    ],
  • "standings": {
    },
  • "featured": {
    },
  • "podium": [
    ],
  • "stats": {
    }
}

Join an Arena tournament

Join an Arena tournament, possibly with a password and/or a team. Also unpauses if you had previously paused the tournament.

Authorizations:
OAuth2
path Parameters
id
required
string
Example: hL7vMrFQ

The tournament ID.

Request Body schema: application/x-www-form-urlencoded
required

You may need these depending on the tournament to join

password
string

The tournament password, if one is required. Can also be a user-specific entry code generated and shared by the organizer.

team
string

The team to join the tournament with, for team battle tournaments

pairMeAsap
boolean
Default: false

If the tournament is started, attempt to pair the user, even if they are not connected to the tournament page. This expires after one minute, to avoid pairing a user who is long gone. You may call "join" again to extend the waiting.

Responses

Response samples

Content type
application/json
{
  • "ok": true
}

Pause or leave an Arena tournament

Leave a future Arena tournament, or take a break on an ongoing Arena tournament. It's possible to join again later. Points and streaks are preserved.

Authorizations:
OAuth2
path Parameters
id
required
string
Example: hL7vMrFQ

The tournament ID.

Responses

Response samples

Content type
application/json
{
  • "ok": true
}

Terminate an Arena tournament

Terminate an Arena tournament

Authorizations:
OAuth2
path Parameters
id
required
string
Example: hL7vMrFQ

The tournament ID.

Responses

Response samples

Content type
application/json
{
  • "ok": true
}

Update a team battle

Set the teams and number of leaders of a team battle.

To update the other attributes of a team battle, use the tournament update endpoint.

Authorizations:
OAuth2
path Parameters
id
required
string

The tournament ID (8 characters)..

Request Body schema: application/x-www-form-urlencoded
required
teams
required
string

All team IDs of the team battle, separated by commas. Make sure to always send the full list. Teams that are not in the list will be removed from the team battle.

Example: coders,zhigalko_sergei-fan-club,hhSwTKZv

nbLeaders
required
integer

Number team leaders per team.

Responses

Response samples

Content type
application/json
{
  • "id": "QITRjufu",
  • "fullName": "U1700 SuperBlitz Arena",
  • "rated": true,
  • "clock": {
    },
  • "minutes": 57,
  • "createdBy": "lichess",
  • "system": "arena",
  • "secondsToStart": 0,
  • "secondsToFinish": 36000,
  • "isFinished": true,
  • "isRecentlyFinished": true,
  • "pairingsClosed": true,
  • "startsAt": 1522803600000,
  • "nbPlayers": 154,
  • "perf": {
    },
  • "schedule": {
    },
  • "variant": "standard",
  • "duels": [
    ],
  • "standings": {
    },
  • "featured": {
    },
  • "podium": [
    ],
  • "stats": {
    }
}

Export games of an Arena tournament

Download games of a tournament in PGN or ndjson format.

Games are sorted by reverse chronological order (most recent first).

The game stream is throttled, depending on who is making the request:

path Parameters
id
required
string

The tournament ID.

query Parameters
player
string

Only games of a particular player. Leave empty to fetch games of all players.

moves
boolean
Default: true

Include the PGN moves.

pgnInJson
boolean
Default: false

Include the full PGN within the JSON response, in a pgn field.

tags
boolean
Default: true

Include the PGN tags.

clocks
boolean
Default: false

Include clock status when available.

Either as PGN comments: 2. exd5 { [%clk 1:01:27] } e5 { [%clk 1:01:28] }

Or in a clocks JSON field, as centisecond integers, depending on the response type.

evals
boolean
Default: false

Include analysis evaluations and comments, when available.

Either as PGN comments: 12. Bxf6 { [%eval 0.23] } a3 { [%eval -1.09] }

Or in an analysis JSON field, depending on the response type.

accuracy
boolean
Default: false

Include accuracy percent of each player, when available.

opening
boolean
Default: false

Include the opening name.

Example: [Opening "King's Gambit Accepted, King's Knight Gambit"]

division
boolean
Default: false

Plies which mark the beginning of the middlegame and endgame. Only available in JSON

Responses

Response samples

Content type
No sample

Get results of an Arena tournament

Players of an Arena tournament, with their score and performance, sorted by rank (best first).

Players are streamed as ndjson, i.e. one JSON object per line.

If called on an ongoing tournament, results can be inconsistent due to ranking changes while the players are being streamed. Use on finished tournaments for guaranteed consistency.

path Parameters
id
required
string

The tournament ID.

query Parameters
nb
integer >= 1

Max number of players to fetch

sheet
boolean
Default: false

Add a sheet field to the player document. It's an expensive server computation that slows down the stream.

Responses

Response samples

Content type
application/x-ndjson
{
  • "rank": 4,
  • "score": 389,
  • "rating": 2618,
  • "username": "opperwezen",
  • "title": "IM",
  • "performance": 2423,
  • "team": "coders"
}

Get team standing of a team battle

Teams of a team battle tournament, with top players, sorted by rank (best first).

path Parameters
id
required
string

The tournament ID.

Responses

Response samples

Content type
application/json
{
  • "id": "CdPg1ey4",
  • "teams": [
    ]
}

Get tournaments created by a user

Get all tournaments created by a given user.

Tournaments are sorted by reverse chronological order of start date (last starting first).

Tournaments are streamed as ndjson.

path Parameters
username
required
string

The user whose created tournaments to fetch

query Parameters
status
integer
Enum: 10 20 30

Include tournaments in the given status: "Created" (10), "Started" (20), "Finished" (30)

You can add this parameter more than once to include tournaments in different statuses.

Example: ?status=10&status=20

Responses

Response samples

Content type
application/x-ndjson
{
  • "id": "QITRjufu",
  • "createdBy": "lichess",
  • "system": "arena",
  • "minutes": 57,
  • "clock": {
    },
  • "rated": true,
  • "fullName": "U1700 SuperBlitz Arena",
  • "nbPlayers": 154,
  • "variant": {
    },
  • "startsAt": 1522803600000,
  • "finishesAt": 1522807200000,
  • "status": 30,
  • "perf": {
    },
  • "secondsToStart": 576,
  • "hasMaxRating": true,
  • "maxRating": {
    },
  • "minRating": {
    },
  • "minRatedGames": {
    },
  • "onlyTitled": false,
  • "teamMember": "coders",
  • "private": true,
  • "position": {},
  • "schedule": {
    },
  • "teamBattle": {
    },
  • "winner": {
    }
}

Get team Arena tournaments

Get all Arena tournaments relevant to a team.

Tournaments are sorted by reverse chronological order of start date (last starting first).

Tournaments are streamed as ndjson.

path Parameters
teamId
required
string

ID of the team

query Parameters
max
integer >= 1
Default: 100

How many tournaments to download.

Responses

Response samples

Content type
application/x-ndjson
{
  • "id": "QITRjufu",
  • "createdBy": "lichess",
  • "system": "arena",
  • "minutes": 57,
  • "clock": {
    },
  • "rated": true,
  • "fullName": "U1700 SuperBlitz Arena",
  • "nbPlayers": 154,
  • "variant": {
    },
  • "startsAt": 1522803600000,
  • "finishesAt": 1522807200000,
  • "status": 30,
  • "perf": {
    },
  • "secondsToStart": 576,
  • "hasMaxRating": true,
  • "maxRating": {
    },
  • "minRating": {
    },
  • "minRatedGames": {
    },
  • "onlyTitled": false,
  • "teamMember": "coders",
  • "private": true,
  • "position": {},
  • "schedule": {
    },
  • "teamBattle": {
    },
  • "winner": {
    }
}

Swiss tournaments

Access Swiss tournaments played on Lichess. Read more about Swiss tournaments..

Create a new Swiss tournament

Create a Swiss tournament for your team.

This endpoint mirrors the Swiss tournament form from your team pagee.

You can create up to 12 tournaments per day.

Additional restrictions:

  • clock.limit + clock.increment > 0
  • 15s and 0+1 variant tournaments cannot be rated
Authorizations:
OAuth2
path Parameters
teamId
required
string

ID of the team

Request Body schema: application/x-www-form-urlencoded
required

Parameters of the tournament

name
string [ 2 .. 30 ] characters

The tournament name. Leave empty to get a random Grandmaster name

clock.limit
required
number
Enum: 0 15 30 45 60 90 120 180 240 300 360 420 480 600 900 1200 1500 1800 2400 3000 3600 4200 4800 5400 6000 6600 7200 7800 8400 9000 9600 10200 10800

Clock initial time in seconds

clock.increment
required
integer [ 0 .. 120 ]

Clock increment in seconds

nbRounds
required
integer [ 3 .. 100 ]

Maximum number of rounds to play

startsAt
integer

Timestamp in milliseconds to start the tournament at a given date and time. By default, it starts 10 minutes after creation.

roundInterval
integer
Enum: -1 5 10 20 30 45 60 120 180 300 600 900 1200 1800 2700 3600 86400 172800 604800 99999999

How long to wait between each round, in seconds.

Set to 99999999 to manually schedule each round from the tournament UI.

If empty or -1, a sensible value is picked automatically.

variant
string (VariantKey)
Enum: "standard" "chess960" "crazyhouse" "antichess" "atomic" "horde" "kingOfTheHill" "racingKings" "threeCheck" "fromPosition"
position
string (FromPositionFEN)

Custom initial position (in FEN). Variant must be standard, fromPosition, or chess960 (if a valid 960 starting position), and the game cannot be rated.

description
string

Anything you want to tell players about the tournament

rated
boolean
Default: true

Games are rated and impact players ratings

password
string

Make the tournament private and restrict access with a password.

forbiddenPairings
string

Usernames of players that must not play together.

Two usernames per line, separated by a space.

manualPairings
string

Manual pairings for the next round.

Two usernames per line, separated by a space. Example:

PlayerA PlayerB
PlayerC PlayerD

To give a bye (1 point) to a player instead of a pairing, add a line like so:

PlayerE 1

Missing players will be considered absent and get zero points.

chatFor
number
Default: 20

Who can read and write in the chat.

  • 0 = No-one
  • 10 = Only team leaders
  • 20 = Only team members
  • 30 = All Lichess players
conditions.minRating.rating
integer
Enum: 1000 1100 1200 1300 1400 1500 1600 1700 1800 1900 2000 2100 2200 2300 2400 2500 2600

Minimum rating to join. Leave empty to let everyone join the tournament.

conditions.maxRating.rating
integer
Enum: 2200 2100 2000 1900 1800 1700 1600 1500 1400 1300 1200 1100 1000 900 800

Maximum rating to join. Based on best rating reached in the last 7 days. Leave empty to let everyone join the tournament.

conditions.nbRatedGame.nb
integer [ 0 .. 200 ]

Minimum number of rated games required to join.

conditions.playYourGames
boolean
Default: false

Only let players join if they have played their last swiss game. If they failed to show up in a recent swiss event, they won't be able to enter yours. This results in a better swiss experience for the players who actually show up.

conditions.allowList
string

Predefined list of usernames that are allowed to join, separated by commas. If this list is non-empty, then usernames absent from this list will be forbidden to join. Adding %titled to the list additionally allows any titled player to join. Example: thibault,german11,%titled

Responses

Response samples

Content type
application/json
{
  • "rated": true,
  • "clock": {
    },
  • "createdBy": "thibault",
  • "id": "ZmKWCOye",
  • "name": "Wang",
  • "nbOngoing": 0,
  • "nbPlayers": 0,
  • "nbRounds": 2,
  • "nextRound": {
    },
  • "round": 0,
  • "startsAt": "2020-05-11T12:23:18.233-06:00",
  • "status": "created",
  • "variant": "standard",
  • "isRecentlyFinished": false,
  • "password": true,
  • "stats": {
    }
}

Get info about a Swiss tournament

Get detailed info about a Swiss tournament.

path Parameters
id
required
string

The Swiss tournament ID.

Responses

Response samples

Content type
application/json
{
  • "rated": true,
  • "clock": {
    },
  • "createdBy": "thibault",
  • "id": "ZmKWCOye",
  • "name": "Wang",
  • "nbOngoing": 0,
  • "nbPlayers": 0,
  • "nbRounds": 2,
  • "nextRound": {
    },
  • "round": 0,
  • "startsAt": "2020-05-11T12:23:18.233-06:00",
  • "status": "created",
  • "variant": "standard",
  • "isRecentlyFinished": false,
  • "password": true,
  • "stats": {
    }
}

Update a Swiss tournament

Update a Swiss tournament.

Be mindful not to make important changes to ongoing tournaments.

Additional restrictions:

  • clock.limit + clock.increment > 0
  • 15s and 0+1 variant tournaments cannot be rated
Authorizations:
OAuth2
path Parameters
id
required
string
Example: hL7vMrFQ

The tournament ID.

Request Body schema: application/x-www-form-urlencoded
required

Parameters of the tournament

name
string [ 2 .. 30 ] characters

The tournament name. Leave empty to get a random Grandmaster name

clock.limit
required
number
Enum: 0 15 30 45 60 90 120 180 240 300 360 420 480 600 900 1200 1500 1800 2400 3000 3600 4200 4800 5400 6000 6600 7200 7800 8400 9000 9600 10200 10800

Clock initial time in seconds

clock.increment
required
integer [ 0 .. 120 ]

Clock increment in seconds

nbRounds
required
integer [ 3 .. 100 ]

Maximum number of rounds to play

startsAt
integer

Timestamp in milliseconds to start the tournament at a given date and time. By default, it starts 10 minutes after creation.

roundInterval
integer
Enum: -1 5 10 20 30 45 60 120 180 300 600 900 1200 1800 2700 3600 86400 172800 604800 99999999

How long to wait between each round, in seconds.

Set to 99999999 to manually schedule each round from the tournament UI, or with the API.

If empty or -1, a sensible value is picked automatically.

variant
string (VariantKey)
Enum: "standard" "chess960" "crazyhouse" "antichess" "atomic" "horde" "kingOfTheHill" "racingKings" "threeCheck" "fromPosition"
description
string

Anything you want to tell players about the tournament

rated
boolean
Default: true

Games are rated and impact players ratings

password
string

Make the tournament private and restrict access with a password.

forbiddenPairings
string

Usernames of players that must not play together.

Two usernames per line, separated by a space.

manualPairings
string

Manual pairings for the next round.

Two usernames per line, separated by a space. Present players without a valid pairing will be given a bye, which is worth 1 point. Forfeited players will get 0 points.

chatFor
number
Default: 20

Who can read and write in the chat.

  • 0 = No-one
  • 10 = Only team leaders
  • 20 = Only team members
  • 30 = All Lichess players
conditions.minRating.rating
integer
Enum: 1000 1100 1200 1300 1400 1500 1600 1700 1800 1900 2000 2100 2200 2300 2400 2500 2600

Minimum rating to join. Leave empty to let everyone join the tournament.

conditions.maxRating.rating
integer
Enum: 2200 2100 2000 1900 1800 1700 1600 1500 1400 1300 1200 1100 1000 900 800

Maximum rating to join. Based on best rating reached in the last 7 days. Leave empty to let everyone join the tournament.

conditions.nbRatedGame.nb
integer [ 0 .. 200 ]

Minimum number of rated games required to join.

conditions.playYourGames
boolean
Default: false

Only let players join if they have played their last swiss game. If they failed to show up in a recent swiss event, they won't be able to enter yours. This results in a better swiss experience for the players who actually show up.

conditions.allowList
string

Predefined list of usernames that are allowed to join, separated by commas. If this list is non-empty, then usernames absent from this list will be forbidden to join. Adding %titled to the list additionally allows any titled player to join. Example: thibault,german11,%titled

Responses

Response samples

Content type
application/json
{
  • "rated": true,
  • "clock": {
    },
  • "createdBy": "thibault",
  • "id": "ZmKWCOye",
  • "name": "Wang",
  • "nbOngoing": 0,
  • "nbPlayers": 0,
  • "nbRounds": 2,
  • "nextRound": {
    },
  • "round": 0,
  • "startsAt": "2020-05-11T12:23:18.233-06:00",
  • "status": "created",
  • "variant": "standard",
  • "isRecentlyFinished": false,
  • "password": true,
  • "stats": {
    }
}

Manually schedule the next round

Manually schedule the next round date and time of a Swiss tournament.

This sets the roundInterval field to 99999999, i.e. manual scheduling.

All further rounds will need to be manually scheduled, unless the roundInterval field is changed back to automatic scheduling.

Authorizations:
OAuth2
path Parameters
id
required
string
Example: hL7vMrFQ

The tournament ID.

Request Body schema: application/x-www-form-urlencoded
required

Parameters of the tournament

date
integer

Timestamp in milliseconds to start the next round at a given date and time.

Responses

Response samples

Content type
application/json
{
  • "error": "This request is invalid because [...]"
}

Join a Swiss tournament

Join a Swiss tournament, possibly with a password.

Authorizations:
OAuth2
path Parameters
id
required
string
Example: hL7vMrFQ

The tournament ID.

Request Body schema: application/x-www-form-urlencoded
required

You may need these depending on the tournament to join

password
string

The tournament password, if one is required

Responses

Response samples

Content type
application/json
{
  • "ok": true
}

Pause or leave a swiss tournament

Leave a future Swiss tournament, or take a break on an ongoing Swiss tournament. It's possible to join again later. Points are preserved.

Authorizations:
OAuth2
path Parameters
id
required
string
Example: hL7vMrFQ

The tournament ID.

Responses

Response samples

Content type
application/json
{
  • "ok": true
}

Terminate a Swiss tournament

Terminate a Swiss tournament

Authorizations:
OAuth2
path Parameters
id
required
string
Example: W5FrxusN

The Swiss tournament ID.

Responses

Response samples

Content type
application/json
{
  • "ok": true
}

Export TRF of a Swiss tournament

Download a tournament in the Tournament Report File format, the FIDE standard.

Documentation: https://www.fide.com/FIDE/handbook/C04Annex2_TRF16.pdf

Example: https://lichess.org/swiss/j8rtJ5GL.trf

path Parameters
id
required
string

The tournament ID.

Responses

Export games of a Swiss tournament

Download games of a swiss tournament in PGN or ndjson format.

Games are sorted by reverse chronological order (last round first).

The game stream is throttled, depending on who is making the request:

path Parameters
id
required
string

The tournament ID.

query Parameters
player
string

Only the games played by a given player

moves
boolean
Default: true

Include the PGN moves.

pgnInJson
boolean
Default: false

Include the full PGN within the JSON response, in a pgn field.

tags
boolean
Default: true

Include the PGN tags.

clocks
boolean
Default: false

Include clock status when available.

Either as PGN comments: 2. exd5 { [%clk 1:01:27] } e5 { [%clk 1:01:28] }

Or in a clocks JSON field, as centisecond integers, depending on the response type.

evals
boolean
Default: false

Include analysis evaluations and comments, when available.

Either as PGN comments: 12. Bxf6 { [%eval 0.23] } a3 { [%eval -1.09] }

Or in an analysis JSON field, depending on the response type.

accuracy
boolean
Default: false

Include accuracy percent of each player, when available.

opening
boolean
Default: false

Include the opening name.

Example: [Opening "King's Gambit Accepted, King's Knight Gambit"]

division
boolean
Default: false

Plies which mark the beginning of the middlegame and endgame. Only available in JSON

Responses

Response samples

Content type
No sample

Get results of a swiss tournament

Players of a swiss tournament, with their score and performance, sorted by rank (best first).

Players are streamed as ndjson.

If called on an ongoing tournament, results can be inconsistent due to ranking changes while the players are being streamed. Use on finished tournaments for guaranteed consistency.

path Parameters
id
required
string

The tournament ID.

query Parameters
nb
integer >= 1

Max number of players to fetch

Responses

Response samples

Content type
application/x-ndjson
{
  • "rank": 4,
  • "points": 8.5,
  • "tieBreak": 77,
  • "rating": 2618,
  • "username": "opperwezen",
  • "title": "IM",
  • "performance": 2423
}

Get team swiss tournaments

Get all swiss tournaments of a team.

Tournaments are sorted by reverse chronological order of start date (last starting first).

Tournaments are streamed as ndjson.

path Parameters
teamId
required
string
Example: coders
query Parameters
max
integer >= 1
Default: 100

How many tournaments to download.

Responses

Response samples

Content type
application/nd-json
{
  • "rated": true,
  • "clock": {
    },
  • "createdBy": "thibault",
  • "id": "ZmKWCOye",
  • "name": "Wang",
  • "nbOngoing": 0,
  • "nbPlayers": 0,
  • "nbRounds": 2,
  • "nextRound": {
    },
  • "round": 0,
  • "startsAt": "2020-05-11T12:23:18.233-06:00",
  • "status": "created",
  • "variant": "standard",
  • "isRecentlyFinished": false,
  • "password": true,
  • "stats": {
    }
}

Simuls

Access simuls played on Lichess. https://lichess.org/simul

Get current simuls

Get recently created, started, finished, simuls.

Created and finished simul lists are not exhaustives, only those with strong enough host will be listed, the same filter is used to display simuls on https://lichess.org/simul.

When authenticated with OAuth2, the pending list will be populated with your created, but unstarted simuls.

Responses

Response samples

Content type
application/json
{
  • "pending": [
    ],
  • "created": [
    ],
  • "started": [
    ],
  • "finished": [
    ]
}

Studies

Access Lichess studies. https://lichess.org/study

Export one study chapter

Download one study chapter in PGN format.

path Parameters
studyId
required
string

The study ID (8 characters).

chapterId
required
string

The chapter ID (8 characters).

query Parameters
clocks
boolean
Default: true

Include clock comments in the PGN moves, when available.

Example: 2. exd5 { [%clk 1:01:27] } e5 { [%clk 1:01:28] }

comments
boolean
Default: true

Include analysis and annotator comments in the PGN moves, when available.

Example: 12. Bxf6 { [%eval 0.23] } a3 { White is in a pickle. }

variations
boolean
Default: true

Include non-mainline moves, when available.

Example: 4. d4 Bb4+ (4... Nc6 5. Nf3 Bb4+ 6. Bd2 (6. Nbd2 O-O 7. O-O) 6... Bd6) 5. Nd2

source
boolean
Default: false

Add a Source PGN tag with the study chapter URL.

Example: [Source "https://lichess.org/study/4NBHImfM/1Tk4IyTz"]

orientation
boolean
Default: false

Add a Orientation PGN tag with the chapter predefined orientation.

Example: [Orientation "white"]

Responses

Export all chapters

Download all chapters of a study in PGN format.

path Parameters
studyId
required
string

The study ID (8 characters).

query Parameters
clocks
boolean
Default: true

Include clock comments in the PGN moves, when available.

Example: 2. exd5 { [%clk 1:01:27] } e5 { [%clk 1:01:28] }

comments
boolean
Default: true

Include analysis and annotator comments in the PGN moves, when available.

Example: 12. Bxf6 { [%eval 0.23] } a3 { White is in a pickle. }

variations
boolean
Default: true

Include non-mainline moves, when available.

Example: 4. d4 Bb4+ (4... Nc6 5. Nf3 Bb4+ 6. Bd2 (6. Nbd2 O-O 7. O-O) 6... Bd6) 5. Nd2

source
boolean
Default: false

Add a Source PGN tag with the study chapter URL.

Example: [Source "https://lichess.org/study/4NBHImfM/1Tk4IyTz"]

orientation
boolean
Default: false

Add a Orientation PGN tag with the chapter predefined orientation.

Example: [Orientation "white"]

Responses

Study metadata

Only get the study headers, including Last-Modified.

path Parameters
studyId
required
string

The study ID (8 characters).

Responses

Import PGN into a study

Imports arbitrary PGN into an existing study. Creates a new chapter in the study.

If the PGN contains multiple games (separated by 2 or more newlines) then multiple chapters will be created within the study.

Note that a study can contain at most 64 chapters.

Authorizations:
OAuth2
path Parameters
studyId
required
string

ID of the study

Request Body schema: application/x-www-form-urlencoded
required

Parameters of the import

name
required
string [ 1 .. 100 ] characters

Name of the new chapter. If multiple chapters are created, the names will be infered from the PGN tags.

pgn
required
string

PGN to import. Can contain multiple games separated by 2 or more newlines.

orientation
string
Default: "white"
Enum: "white" "black"

Default board orientation.

variant
string (VariantKey)
Enum: "standard" "chess960" "crazyhouse" "antichess" "atomic" "horde" "kingOfTheHill" "racingKings" "threeCheck" "fromPosition"

Responses

Response samples

Content type
application/json
{
  • "chapters": [
    ]
}

Export all studies of a user

Download all chapters of all studies of a user in PGN format.

If authenticated, then all public, unlisted, and private studies are included.

If not, only public (non-unlisted) studies are included.

Authorizations:
OAuth2
path Parameters
username
required
string

The user whose studies we export

query Parameters
clocks
boolean
Default: true

Include clock comments in the PGN moves, when available.

Example: 2. exd5 { [%clk 1:01:27] } e5 { [%clk 1:01:28] }

comments
boolean
Default: true

Include analysis and annotator comments in the PGN moves, when available.

Example: 12. Bxf6 { [%eval 0.23] } a3 { White is in a pickle. }

variations
boolean
Default: true

Include non-mainline moves, when available.

Example: 4. d4 Bb4+ (4... Nc6 5. Nf3 Bb4+ 6. Bd2 (6. Nbd2 O-O 7. O-O) 6... Bd6) 5. Nd2

source
boolean
Default: false

Add a Source PGN tag with the study chapter URL.

Example: [Source "https://lichess.org/study/4NBHImfM/1Tk4IyTz"]

orientation
boolean
Default: false

Add a Orientation PGN tag with the chapter predefined orientation.

Example: [Orientation "white"]

Responses

List studies of a user

Get metadata (name and dates) of all studies of a user.

If authenticated, then all public, unlisted, and private studies are included.

If not, only public (non-unlisted) studies are included.

Studies are streamed as ndjson.

Authorizations:
OAuth2
path Parameters
username
required
string

The user whose studies we list

Responses

Response samples

Content type
application/x-ndjson
[
  • {
    }
]

Messaging

Private messages with other players. https://lichess.org/inbox

Send a private message

Send a private message to another player.

Authorizations:
OAuth2
path Parameters
username
required
string
Example: someplayer
Request Body schema: application/x-www-form-urlencoded
required
text
required
string

Responses

Response samples

Content type
application/json
{
  • "ok": true
}

Broadcasts

Relay chess events on Lichess. Official broadcasts are maintained by Lichess, but you can create your own broadcasts to cover any live game or chess event. You will need to publish PGN on a public URL so that Lichess can pull updates from it. Alternatively, you can push PGN updates to Lichess using this API endpoint.

Broadcasts are organized in tournaments, which have several rounds, which have several games. You must first create a tournament, then you can add rounds to them.

Get official broadcasts

Get all incoming, ongoing, and finished official broadcasts. The broadcasts are sorted by start date, most recent first.

Broadcasts are streamed as ndjson.

query Parameters
nb
integer >= 1
Default: 20

Max number of broadcasts to fetch

Responses

Response samples

Content type
application/x-ndjson
[]

Create a broadcast tournament

Create a new broadcast tournament to relay external games. This endpoint accepts the same form data as the web form.

Authorizations:
OAuth2
Request Body schema: application/x-www-form-urlencoded
required
name
required
string

Name of the broadcast tournament. Length must be between 3 and 80 characters.

Example: Sinquefield Cup

description
required
string

Short description of the broadcast tournament. Length must be between 3 and 400 characters.

Example: An 11 round classical tournament featuring the 9 highest rated players in the world. Including Carlsen, Caruana, Ding, Aronian, Nakamura and more.

autoLeaderboard
required
boolean

Compute and display a simple leaderboard based on game results

markdown
string

Optional long description of the broadcast. Markdown is supported. Length must be less than 20,000 characters.

tier
integer

Optional, for Lichess admins only, use to feature on /broadcast.

  • 3 for normal
  • 4 for high
  • 5 for best
players
any

Optional replace player names, ratings and titles.

One line per player, formatted as such:

Original name; Replacement name; Optional replacement rating; Optional replacement title

Example:

DrNykterstein;Magnus Carlsen;2863

AnishGiri;Anish Giri;2764;GM

Responses

Response samples

Content type
application/json
{}

Get your broadcast tournament

Get information about a broadcast tournament.

Authorizations:
OAuth2
path Parameters
slug
required
string

The broadcast tournament slug. Only used for SEO, the slug can be safely replaced by -. Only the broadcastTournamentId is actually used.

broadcastTournamentId
required
string

The broadcast tournament ID (8 characters).

Responses

Response samples

Content type
application/json
{}

Update your broadcast tournament

Update information about a broadcast tournament that you created. This endpoint accepts the same form data as the web form. All fields must be populated with data. Missing fields will override the broadcast with empty data.

Authorizations:
OAuth2
path Parameters
broadcastTournamentId
required
string

The broadcast ID (8 characters).

Request Body schema: application/x-www-form-urlencoded
required
name
required
string

Name of the broadcast tournament. Length must be between 3 and 80 characters.

Example: Sinquefield Cup

description
required
string

Short description of the broadcast tournament. Length must be between 3 and 400 characters.

Example: An 11 round classical tournament featuring the 9 highest rated players in the world. Including Carlsen, Caruana, Ding, Aronian, Nakamura and more.

autoLeaderboard
required
boolean

Compute and display a simple leaderboard based on game results

markdown
string

Optional long description of the broadcast. Markdown is supported. Length must be less than 20,000 characters.

tier
integer

Optional, for Lichess admins only, use to feature on /broadcast.

  • 3 for normal
  • 4 for high
  • 5 for best
players
any

Optional replace player names, ratings and titles.

One line per player, formatted as such:

Original name; Replacement name; Optional replacement rating; Optional replacement title

Example:

DrNykterstein;Magnus Carlsen;2863

AnishGiri;Anish Giri;2764;GM

Responses

Response samples

Content type
application/json
{
  • "ok": true
}

Create a broadcast round

Create a new broadcast round to relay external games. This endpoint accepts the same form data as the web form.

Authorizations:
OAuth2
path Parameters
broadcastTournamentId
required
string

The broadcast tournament ID (8 characters).

Request Body schema: application/x-www-form-urlencoded
required
name
required
string

Name of the broadcast round. Length must be between 3 and 80 characters.

Example: Round 1

syncUrl
string

URL that Lichess will poll to get updates about the games. It must be publicly accessible from the Internet.

Example: https://myserver.org/myevent/round-10/games.pgn

If the syncUrl is missing, then the broadcast needs to be fed by pushing PGN to it.

syncUrlRound
string

Required if syncUrl contains a livechesscloud link.

startsAt
integer >= 1356998400070

Timestamp in milliseconds of broadcast round start. Leave empty to manually start the broadcast round.

Example: 1356998400070

delay
integer [ 0 .. 1800 ]

Delay in seconds for movements to appear on the broadcast. Leave it empty if you don't need it.

Example: 900 (15 min)

period
integer [ 2 .. 60 ]

(Only for Admins) Waiting time for each poll.

finished
boolean
Default: false

Mark whether the round has been completed.

Responses

Response samples

Content type
application/json
{}

Get a broadcast round

Get information about a broadcast round.

path Parameters
broadcastTournamentSlug
required
string

The broadcast tournament slug. Only used for SEO, the slug can be safely replaced by -. Only the broadcastRoundId is actually used.

broadcastRoundSlug
required
string

The broadcast round slug. Only used for SEO, the slug can be safely replaced by -. Only the broadcastRoundId is actually used.

broadcastRoundId
required
string

The broadcast Round ID (8 characters).

Responses

Response samples

Content type
application/json
{}

Update your broadcast round

Update information about a broadcast round that you created. This endpoint accepts the same form data as the web form. All fields must be populated with data. Missing fields will override the broadcast with empty data. For instance, if you omit startDate, then any pre-existing start date will be removed.

Authorizations:
OAuth2
path Parameters
broadcastRoundId
required
string

The broadcast round ID (8 characters).

Request Body schema: application/x-www-form-urlencoded
required
name
required
string

Name of the broadcast round. Length must be between 3 and 80 characters.

Example: Round 10

syncUrl
string

URL that Lichess will poll to get updates about the games. It must be publicly accessible from the Internet.

Example: https://myserver.org/myevent/round-10/games.pgn

syncUrlRound
string

Required if syncUrl contains a livechesscloud link.

startsAt
integer >= 1356998400070

Timestamp in milliseconds of broadcast start. Leave empty to manually start the broadcast.

Example: 1356998400070

delay
integer [ 0 .. 1800 ]

Delay in seconds for movements to appear on the broadcast. Leave it empty if you don't need it.

Example: 900 (15 min)

period
integer [ 2 .. 60 ]

(Only for Admins) Waiting time for each poll.

finished
boolean
Default: false

Mark whether the round has been completed.

Responses

Response samples

Content type
application/json
{
  • "ok": true
}

Push PGN to your broadcast round

Update your broadcast with new PGN. Only for broadcast without a source URL.

Authorizations:
OAuth2
path Parameters
broadcastRoundId
required
string

The broadcast round ID (8 characters).

Request Body schema: text/plain
required

The PGN. It can contain up to 64 games, separated by a double new line.

string

Responses

Response samples

Content type
application/json
{
  • "moves": 12
}

Stream an ongoing broadcast tournament as PGN

This streaming endpoint first sends all games of a broadcast tournament in PGN format.

Then, it waits for new moves to be played. As soon as it happens, the entire PGN of the game is sent to the stream.

The stream will also send PGNs when games are added to the tournament.

This is the best way to get updates about an ongoing tournament. Streaming means no polling, and no pollings means no latency, and minimum impact on the server.

path Parameters
broadcastRoundId
required
string

The broadcast round ID (8 characters).

Responses

Export one round as PGN

Download all games of a single round of a broadcast tournament in PGN format.

You could poll this endpoint to get updates about a tournament, but it would be slow, and very inneficient.

Instead, consider streaming the tournament to get a new PGN every time a game is updated, in real-time.

path Parameters
broadcastRoundId
required
string

The round ID (8 characters).

Responses

Export all rounds as PGN

Download all games of all rounds of a broadcast in PGN format.

If a study:read OAuth token is provided, the private rounds where the user is a contributor will be available.

You may want to download only the games of a single round instead.

Authorizations:
OAuth2
path Parameters
broadcastTournamentId
required
string

The broadcast tournament ID (8 characters).

Responses

Get your broadcast rounds

Stream all broadcast rounds you are a member of. Also includes broadcasts rounds you did not create, but were invited to. Also includes broadcasts rounds where you're a non-writing member. See the writeable flag in the response. Rounds are ordered by rank, which is roughly chronological, most recent first, slightly pondered with popularity.

Authorizations:
OAuth2
query Parameters
nb
integer >= 1
Example: nb=20

How many rounds to get

Responses

Response samples

Content type
application/json
{
  • "tour": {
    },
  • "round": {},
  • "study": {
    }
}

Analysis

Access Lichess cloud evaluations database. https://lichess.org/analysis

Get cloud evaluation of a position.

Get the cached evaluation of a position, if available.

Opening positions have more chances of being available. There are about 15 million positions in the database.

Up to 5 variations may be available. Variants are supported.

Use this endpoint to fetch a few positions here and there. If you want to download a lot of positions, get the full list from our exported database.

query Parameters
fen
required
string
Example: fen=rnbqkbnr/ppp1pppp/8/3pP3/8/8/PPPP1PPP/RNBQKBNR b KQkq - 0 2

FEN of the position

multiPv
number
Default: 1

Number of variations

variant
string (VariantKey)
Default: "standard"
Enum: "standard" "chess960" "crazyhouse" "antichess" "atomic" "horde" "kingOfTheHill" "racingKings" "threeCheck" "fromPosition"
Example: variant=standard

Variant

Responses

Response samples

Content type
application/json
{
  • "fen": "rnbqkbnr/ppp1pppp/8/3pP3/8/8/PPPP1PPP/RNBQKBNR b KQkq - 0 2",
  • "knodes": 13683,
  • "depth": 22,
  • "pvs": [
    ]
}

External engine

This API is in alpha and subject to change.

Use or provide external engine analysis.

External engines can provide analysis on pages like the analysis board, running as a service outside of the browser, or even on a different machine.

List external engines

Lists all external engines that have been registered for the user, and the credentials required to use them.

Authorizations:
OAuth2

Responses

Response samples

Content type
application/json
[
  • {
    }
]

Create external engine

Registers a new external engine for the user. It can then be selected and used on the analysis board.

After registering, the provider should start waiting for analyis requests.

Authorizations:
OAuth2
Request Body schema: application/json
required

A new external engine registration.

name
required
string [ 3 .. 200 ] characters

Display name of the engine.

maxThreads
required
integer [ 1 .. 65536 ]

Maximum number of available threads.

maxHash
required
integer [ 1 .. 1048576 ]

Maximum available hash table size, in MiB.

defaultDepth
required
integer [ 0 .. 246 ]

Estimated depth of normal search.

variants
Array of strings (UciVariant)
Items Enum: "chess" "crazyhouse" "antichess" "atomic" "horde" "kingofthehill" "racingkings" "3check"

Optional list of supported chess variants.

providerSecret
required
string [ 16 .. 1024 ] characters

A random token that can be used to wait for analysis requests and provide analysis.

The engine provider should securely generate a random string.

The token will not be readable again, even by the user.

The analysis provider can register multiple engines with the same token, even for different users, and wait for analysis requests from any of them. In this case, the request must not be made via CORS, so that the token is not revealed to any of the users.

providerData
string

Arbitrary data that the engine provider can use for identification or bookkeeping.

Users can read this information, but updating it requires knowing or changing the providerSecret.

Responses

Request samples

Content type
application/json
{
  • "name": "Stockfish 15",
  • "maxThreads": 8,
  • "maxHash": 2048,
  • "defaultDepth": 24,
  • "variants": [
    ],
  • "providerSecret": "Dee3uwieZei9ahpaici9bee2yahsai0K",
  • "providerData": "string"
}

Response samples

Content type
application/json
{
  • "id": "eei_aTKImBJOnv6j",
  • "name": "Stockfish 15",
  • "clientSecret": "ees_mdF2hK0hlKGSPeC6",
  • "userId": "thibault",
  • "maxThreads": 8,
  • "maxHash": 2048,
  • "defaultDepth": 24,
  • "variants": [
    ],
  • "providerData": "string"
}

Get external engine

Get properties and credentials of an external engine.

Authorizations:
OAuth2
path Parameters
id
required
string
Example: eei_aTKImBJOnv6j

The external engine id.

Responses

Response samples

Content type
application/json
{
  • "id": "eei_aTKImBJOnv6j",
  • "name": "Stockfish 15",
  • "clientSecret": "ees_mdF2hK0hlKGSPeC6",
  • "userId": "thibault",
  • "maxThreads": 8,
  • "maxHash": 2048,
  • "defaultDepth": 24,
  • "variants": [
    ],
  • "providerData": "string"
}

Update external engine

Updates the properties of an external engine.

Authorizations:
OAuth2
path Parameters
id
required
string
Example: eei_aTKImBJOnv6j

The external engine id.

Request Body schema: application/json
required

A modified engine registration.

name
required
string [ 3 .. 200 ] characters

Display name of the engine.

maxThreads
required
integer [ 1 .. 65536 ]

Maximum number of available threads.

maxHash
required
integer [ 1 .. 1048576 ]

Maximum available hash table size, in MiB.

defaultDepth
required
integer [ 0 .. 246 ]

Estimated depth of normal search.

variants
Array of strings (UciVariant)
Items Enum: "chess" "crazyhouse" "antichess" "atomic" "horde" "kingofthehill" "racingkings" "3check"

Optional list of supported chess variants.

providerSecret
required
string [ 16 .. 1024 ] characters

A random token that can be used to wait for analysis requests and provide analysis.

The engine provider should securely generate a random string.

The token will not be readable again, even by the user.

The analysis provider can register multiple engines with the same token, even for different users, and wait for analysis requests from any of them. In this case, the request must not be made via CORS, so that the token is not revealed to any of the users.

providerData
string

Arbitrary data that the engine provider can use for identification or bookkeeping.

Users can read this information, but updating it requires knowing or changing the providerSecret.

Responses

Request samples

Content type
application/json
{
  • "name": "Stockfish 15",
  • "maxThreads": 8,
  • "maxHash": 2048,
  • "defaultDepth": 24,
  • "variants": [
    ],
  • "providerSecret": "Dee3uwieZei9ahpaici9bee2yahsai0K",
  • "providerData": "string"
}

Response samples

Content type
application/json
{
  • "id": "eei_aTKImBJOnv6j",
  • "name": "Stockfish 15",
  • "clientSecret": "ees_mdF2hK0hlKGSPeC6",
  • "userId": "thibault",
  • "maxThreads": 8,
  • "maxHash": 2048,
  • "defaultDepth": 24,
  • "variants": [
    ],
  • "providerData": "string"
}

Delete external engine

Unregisters an external engine.

Authorizations:
OAuth2
path Parameters
id
required
string
Example: eei_aTKImBJOnv6j

The external engine id.

Responses

Response samples

Content type
application/json
{
  • "ok": true
}

Analyse with external engine

Endpoint: https://engine.lichess.ovh/api/external-engine/{id}/analyse

Request analysis from an external engine.

Response content is streamed as newline delimited JSON. The properties are based on the UCI specification. Analysis stops when the client goes away, the requested limit is reached, or the provider goes away.

path Parameters
id
required
string
Example: eei_aTKImBJOnv6j

The external engine id.

Request Body schema: application/json
required

Engine credentials and analysis request.

clientSecret
required
string
required
object (ExternalEngineWork)

Responses

Request samples

Content type
application/json
{
  • "clientSecret": "ees_mdF2hK0hlKGSPeC6",
  • "work": {
    }
}

Response samples

Content type
application/x-ndjson
{
  • "time": 6880,
  • "depth": 25,
  • "nodes": 7230340,
  • "pvs": [
    ]
}

Acquire analysis request

Endpoint: https://engine.lichess.ovh/api/external-engine/work

Wait for an analysis requests to any of the external engines that have been registered with the given secret.

Uses long polling.

After acquiring a request, the provider should immediately start streaming the results.

Request Body schema: application/json
required

Provider credentials.

providerSecret
string

Responses

Request samples

Content type
application/json
{
  • "providerSecret": "Dee3uwieZei9ahpaici9bee2yahsai0K"
}

Response samples

Content type
application/json
{
  • "id": "aingoohiJee2sius",
  • "work": {
    },
  • "engine": {
    }
}

Answer analysis request

Endpoint: https://engine.lichess.ovh/api/external-engine/work/{id}

Submit a stream of analysis as UCI output.

  • The engine should always be in UCI_Chess960 mode.
  • UCI_AnalyseMode enabled if available.
  • It produces info with at least:
    • depth
    • multipv (between 1 and 5)
    • score
    • nodes
    • time
    • pv

The server may close the connection at any time, indicating that the requester has gone away and analysis should be stopped.

path Parameters
id
required
string
Example: aingoohiJee2sius
Request Body schema: text/plain
required

Analysis results

string

Responses

Request samples

Content type
text/plain
info multipv 1 depth 20 seldepth 30 time 1373 nodes 1494341 score cp 47 hashfull 594 nps 1088376 tbhits 0 pv d2d4 d7d5 c2c4 e7e6 b1c3 f8b4 c4d5 e6d5 g1f3 g8f6 c1g5 h7h6 g5f6 d8f6 d1b3 c7c5 e2e3 b8c6 d4c5 e8g8 f1d3

Opening Explorer

Lookup positions from the Lichess opening explorer.

Runs https://github.com/niklasf/lila-openingexplorer.

The endpoint hostname is not lichess.org but explorer.lichess.ovh.

Masters database

Endpoint: https://explorer.lichess.ovh/masters

Example: curl https://explorer.lichess.ovh/masters?play=d2d4,d7d5,c2c4,c7c6,c4d5

query Parameters
fen
string
Example: fen=rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1

FEN of the root position

play
string
Default: ""
Example: play=e2e4,e7e5,c2c4,c7c6,c4e5

Comma separated sequence of legal moves in UCI notation. Play additional moves starting from fen. Required to find an opening name, if fen is not an exact match for a named position.

since
number
Default: 1952

Include only games from this year or later

until
number

Include only games from this year or earlier

moves
number
Default: 12

Number of most common moves to display

topGames
number <= 15
Default: 15

Number of top games to display

Responses

Response samples

Content type
application/json
{
  • "opening": {
    },
  • "white": 1443,
  • "draws": 3787,
  • "black": 1156,
  • "moves": [
    ],
  • "topGames": [
    ],
  • "recentGames": [ ],
  • "history": [
    ]
}

Lichess games

Endpoint: https://explorer.lichess.ovh/lichess

Games sampled from all Lichess players.

Example: curl https://explorer.lichess.ovh/lichess?variant=standard&speeds=blitz,rapid,classical&ratings=2200,2500&fen=rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR%20w%20KQkq%20-%200%201

query Parameters
variant
string (VariantKey)
Default: "standard"
Enum: "standard" "chess960" "crazyhouse" "antichess" "atomic" "horde" "kingOfTheHill" "racingKings" "threeCheck" "fromPosition"
Example: variant=standard

Variant

fen
string
Example: fen=rnbqkbnr/ppp1pppp/8/3pP3/8/8/PPPP1PPP/RNBQKBNR b KQkq - 0 2

FEN or EPD of the root position

play
string
Default: ""
Example: play=e2e4,e7e5,c2c4,c7c6,c4e5

Comma separated sequence of legal moves in UCI notation. Play additional moves starting from fen. Required to find an opening name, if fen is not an exact match for a named position.

speeds
Array of strings (Speed)
Items Enum: "ultraBullet" "bullet" "blitz" "rapid" "classical" "correspondence"

Comma separated list of game speeds to filter by

ratings
Array of numbers
Items Enum: 0 1000 1200 1400 1600 1800 2000 2200 2500

Comma separated list of ratings groups to filter by. Each group ranges from its value to the next higher group in the enum (0 from 0 to 999, 1000 from 1000 to 1199, ..., 2500 from 2500 to any rating above).

since
string
Default: "1952-01"

Include only games from this month or later

until
string
Default: "3000-12"

Include only games from this month or earlier

moves
number
Default: 12

Number of most common moves to display

topGames
number <= 4
Default: 4

Number of top games to display

recentGames
number <= 4
Default: 4

Number of recent games to display

history
boolean
Default: false

Optionally retrieve history

Responses

Response samples

Content type
application/json
{
  • "opening": {
    },
  • "white": 1443,
  • "draws": 3787,
  • "black": 1156,
  • "moves": [
    ],
  • "topGames": [
    ],
  • "recentGames": [ ],
  • "history": [
    ]
}

Player games

Endpoint: https://explorer.lichess.ovh/player

Games of a Lichess player.

Responds with a stream of newline delimited JSON. Will start indexing on demand, immediately respond with the current results, and stream more updates until indexing is complete. The stream is throttled and deduplicated. Empty lines may be sent to avoid timeouts.

Will index new games at most once per minute, and revisit previously ongoing games at most once every day.

Example: curl https://explorer.lichess.ovh/player?player=revoof&color=white&play=d2d4,d7d5&recentGames=1

query Parameters
player
string
Example: player=revoof

Username or ID of the player

variant
string (VariantKey)
Default: "standard"
Enum: "standard" "chess960" "crazyhouse" "antichess" "atomic" "horde" "kingOfTheHill" "racingKings" "threeCheck" "fromPosition"
Example: variant=standard

Variant

fen
string
Example: fen=rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1

FEN of the root position

play
string
Default: ""
Example: play=d2d4,d7d5

Comma separated sequence of legal moves in UCI notation. Play additional moves starting from fen. Required to find an opening name, if fen is not an exact match for a named position.

speeds
Array of strings (Speed)
Items Enum: "ultraBullet" "bullet" "blitz" "rapid" "classical" "correspondence"

Comma separated list of game speeds to look for

modes
Array of strings
Items Enum: "casual" "rated"

Comma separated list of modes

since
string
Default: "1952-01"

Include only games from this month or later

until
string
Default: "3000-12"

Include only games from this month or earlier

moves
number

Number of most common moves to display

recentGames
number <= 8
Default: 8

Number of recent games to display

Responses

Response samples

Content type
application/nd-json
{
  • "white": 359,
  • "draws": 23,
  • "black": 273,
  • "moves": [
    ],
  • "recentGames": [
    ],
  • "opening": {
    },
  • "queuePosition": 0
}

OTB master game

Endpoint: https://explorer.lichess.ovh/masters/pgn/{gameId}

Example: curl https://explorer.lichess.ovh/masters/pgn/aAbqI4ey

path Parameters
gameId
required
string

Responses

Tablebase

Lookup positions from the Lichess tablebase server.

The endpoint hostname is not lichess.org but tablebase.lichess.ovh.

Tablebase lookup

Endpoint: https://tablebase.lichess.ovh

Example: curl http://tablebase.lichess.ovh/standard?fen=4k3/6KP/8/8/8/8/7p/8_w_-_-_0_1

query Parameters
fen
required
string

FEN of the position. Underscores allowed.

Responses

Response samples

Content type
application/json
{
  • "dtz": 1,
  • "precise_dtz": 1,
  • "dtm": 17,
  • "checkmate": false,
  • "stalemate": false,
  • "variant_win": false,
  • "variant_loss": false,
  • "insufficient_material": false,
  • "category": "win",
  • "moves": [
    ]
}

Tablebase lookup for Atomic chess

Responses

Tablebase lookup for Antichess

Responses

Request authorization code

OAuth2 authorization endpoint.

Start the OAuth2 Authorization Code Flow with PKCE by securely generating two random strings unique to each authorization request:

  • code_verifier
  • state

Store these in session storage. Make sure not to reveal code_verifier to eavesdroppers. Do not show it in URLs, do not abuse state to store it, do not send it over insecure connections. However it is fine if the user themselves can extract code_verifier, which will always be possible for fully client-side apps.

Then send the user to this endpoint. They will be prompted to grant authorization and then be redirected back to the given redirect_uri.

If the authorization failed, the following query string parameters will be appended to the redirection:

  • error, in particular with value access_denied if the user cancelled authorization
  • error_description to aid debugging
  • state, exactly as passed in the state parameter

If the authorization succeeded, the following query string parameters will be appended to the redirection:

  • code, containing a fresh short-lived authorization code
  • state, exactly as passed in the state parameter

Next, to defend against cross site request forgery, check that the returned state matches the state you originally generated.

Finally, continue by using the authorization code to obtain an access token.

query Parameters
response_type
required
string

Must be code.

client_id
required
string
Example: client_id=example.com

Arbitrary identifier that uniquely identifies your application.

redirect_uri
required
string

The absolute URL that the user should be redirected to with the authorization result.

code_challenge_method
required
string

Must be S256.

code_challenge
required
string

Compute BASE64URL(SHA256(code_verifier)).

scope
string

Space separated list of requested OAuth scopes, if any.

username
string

Hint that you want the user to log in with a specific Lichess username.

state
string

Arbitrary state that will be returned verbatim with the authorization result.

Responses

Obtain access token

OAuth2 token endpoint. Exchanges an authorization code for an access token.

Request Body schema: application/x-www-form-urlencoded
required
grant_type
string

Must be authorization_code.

code
string

The authorization code that was sent in the code parameter to your redirect_uri.

code_verifier
string

A code_challenge was used to request the authorization code. This must be the code_verifier it was derived from.

redirect_uri
string

Must match the redirect_uri used to request the authorization code.

client_id
string

Must match the client_id used to request the authorization code.

Responses

Response samples

Content type
application/json
{
  • "token_type": "Bearer",
  • "access_token": "lio_pLwAbN7lFPklzY2m8lTOI1DGApS84u57",
  • "expires_in": 31536000
}

Revoke access token

Revokes the access token sent as Bearer for this request.

Authorizations:
OAuth2

Responses

Test multiple OAuth tokens

For up to 1000 OAuth tokens, returns their associated user ID and scopes, or null if the token is invalid.

The method is POST so a longer list of tokens can be sent in the request body.

Request Body schema: text/plain
required

OAuth tokens separated by commas. Up to 1000.

string

Responses

Request samples

Content type
text/plain
lip_AvsS88TozFeSMEaoLN5c,lip_badToken

Response samples

Content type
application/json
{
  • "lip_AvsS88TozFeSnZa1LN5c": {
    },
  • "lip_badToken": null
}