openapi: 3.1.0
info:
version: 2.0.144
title: Lichess.org API reference Account Broadcasts API
contact:
name: Lichess.org API
url: https://lichess.org/api
email: contact@lichess.org
x-logo:
url: https://lichess1.org/assets/logo/lichess-pad12.svg
license:
name: AGPL-3.0-or-later
url: https://www.gnu.org/licenses/agpl-3.0.txt
description: '# Introduction
Welcome to the reference for the Lichess API! Lichess is free/libre,
open-source chess server powered by volunteers and donations.
- Get help in the [Lichess Discord channel](https://discord.gg/lichess)
- API demo app with OAuth2 login and gameplay: [source](https://github.com/lichess-org/api-demo) / [demo](https://lichess-org.github.io/api-demo/)
- API UI app with OAuth2 login and endpoint forms: [source](https://github.com/lichess-org/api-ui) / [website](https://lichess.org/api/ui)
- [Contribute to this documentation on Github](https://github.com/lichess-org/api)
- Check out [Lichess widgets to embed in your website](https://lichess.org/developers)
- [Download all Lichess rated games](https://database.lichess.org/)
- [Download all Lichess puzzles with themes, ratings and votes](https://database.lichess.org/#puzzles)
- [Download all evaluated positions](https://database.lichess.org/#evals)
## Endpoint
All requests go to `https://lichess.org` (unless otherwise specified).
## Clients
- [Python general API](https://github.com/lichess-org/berserk)
- [MicroPython general API](https://github.com/mkomon/uberserk)
- [Python general API - async](https://pypi.org/project/async-lichess-sdk)
- [Python Lichess Bot](https://github.com/lichess-bot-devs/lichess-bot)
- [Python Board API for Certabo](https://github.com/haklein/certabo-lichess)
- [Java general API](https://github.com/tors42/chariot)
- [JavaScript & TypeScript general API](https://github.com/devjiwonchoi/equine)
- [LichessNET - C# API Wrapper](https://github.com/Rabergsel/LichessNET)
- [.NET general API](https://github.com/Dblike/LichessSharp)
## 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](https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#429),
you have exceded one of the rate limits.
In most cases, waiting one minute before retrying will be sufficient, but some limits may require longer.
Reduce your request frequency before retrying.
## Streaming with ND-JSON
Some API endpoints stream their responses as [Newline Delimited JSON a.k.a. **nd-json**](https://github.com/ndjson/ndjson-spec), with one JSON object per line.
Here''s a [JavaScript utility function](https://gist.github.com/ornicar/a097406810939cf7be1df8ea30e94f3e) to help reading NDJSON streamed responses.
## Authentication
### Which authentication method is right for me?
[Read about the Lichess API authentication methods and code examples](https://github.com/lichess-org/api/blob/master/example/README.md)
### Personal Access Token
Personal API access tokens allow you to quickly interact with Lichess API without going through an OAuth flow.
- [Generate a personal access token](https://lichess.org/account/oauth/token)
- `curl https://lichess.org/api/account -H "Authorization: Bearer {token}"`
- [NodeJS example](https://github.com/lichess-org/api/tree/master/example/oauth-personal-token)
### Token Security
- Keep your tokens secret. Do not share them in public repositories or public forums.
- Your tokens can be used to make your account perform arbitrary actions (within the limits of the tokens'' scope). You remain responsible for all activities on your account.
- Do not hardcode tokens in your application''s code. Use environment variables or a secure storage and ensure they are not shipped/exposed to users. Be especially careful that they are not included in frontend bundles or apps that are shipped to users.
- If you suspect a token has been compromised, revoke it immediately.
To see your active tokens or revoke them, see [your Personal API access tokens](https://lichess.org/account/oauth/token).
### 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](#tag/OAuth) or
the [PKCE RFC](https://datatracker.ietf.org/doc/html/rfc7636#section-4) for a precise protocol description.
- [Demo app](https://lichess-org.github.io/api-demo/)
- [Minimal client-side example](https://github.com/lichess-org/api/tree/master/example/oauth-app)
- [Flask/Python example](https://github.com/lakinwecker/lichess-oauth-flask)
- [Java example](https://github.com/tors42/lichess-oauth-pkce-app)
- [NodeJS Passport strategy to login with Lichess OAuth2](https://www.npmjs.com/package/passport-lichess)
#### Real life examples
- [PyChess](https://github.com/gbtami/pychess-variants) ([source code](https://github.com/gbtami/pychess-variants))
- [Lichess4545](https://www.lichess4545.com/) ([source code](https://github.com/cyanfish/heltour))
- [English Chess Federation](https://ecf.octoknight.com/)
- [Rotherham Online Chess](https://rotherhamonlinechess.azurewebsites.net/tournaments)
### 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.
'
servers:
- url: https://lichess.org
- url: https://lichess.dev
- url: http://localhost:{port}
variables:
port:
default: '8080'
- url: http://l.org
tags:
- name: Broadcasts
description: 'Relay chess events on Lichess.
[Official broadcasts](https://lichess.org/broadcast) are maintained by Lichess,
but you can [create your own broadcasts](https://lichess.org/broadcast/new) 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](#tag/broadcasts/POST/api/broadcast/round/{broadcastRoundId}/push).
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.
'
paths:
/api/broadcast:
get:
operationId: broadcastsOfficial
summary: Get official broadcasts
description: "Returns active (a round is scheduled or ongoing) official broadcasts sorted by tier. \nAfter that, returns finished broadcasts sorted by most recent sync time.\nBroadcasts are streamed as [ndjson](#description/streaming-with-nd-json).\n"
tags:
- Broadcasts
security: []
parameters:
- in: query
name: nb
description: Max number of broadcasts to fetch
schema:
type: integer
default: 20
minimum: 1
maximum: 100
- in: query
name: html
description: Convert the "description" field from markdown to HTML
schema:
type: boolean
example: true
- in: query
name: live
description: '[Filter] only broadcasts where a round is ongoing, i.e. started and not finished'
schema:
type: boolean
example: true
responses:
'200':
description: The list of official broadcasts.
headers:
Access-Control-Allow-Origin:
schema:
type: string
default: '''*'''
content:
application/x-ndjson:
schema:
$ref: '#/components/schemas/BroadcastWithRounds'
examples:
default:
$ref: '#/components/examples/broadcasts-getOfficialBroadcasts.json'
/api/broadcast/top:
get:
operationId: broadcastsTop
summary: Get paginated top broadcast previews
description: 'The same data, in the same order, as can be seen on [https://lichess.org/broadcast](/broadcast).
'
tags:
- Broadcasts
security: []
parameters:
- in: query
name: page
description: Which page to fetch. Only page 1 has "active" broadcasts.
schema:
type: integer
default: 1
minimum: 1
maximum: 20
- in: query
name: html
description: Convert the "description" field from markdown to HTML
schema:
type: boolean
example: true
responses:
'200':
description: Paginated top broadcast previews.
headers:
Access-Control-Allow-Origin:
schema:
type: string
default: '''*'''
content:
application/json:
schema:
$ref: '#/components/schemas/BroadcastTop'
examples:
default:
$ref: '#/components/examples/broadcasts-getPaginatedToBroadcastPreviews.json'
/api/broadcast/by/{username}:
get:
operationId: broadcastsByUser
summary: Get broadcasts created by a user
description: 'Get all incoming, ongoing, and finished official broadcasts.
The broadcasts are sorted by created date, most recent first.
If you are authenticated as the user whose broadcasts you are requesting, you will also see your private and unlisted broadcasts.
'
tags:
- Broadcasts
security:
- OAuth2:
- study:read
parameters:
- in: path
name: username
schema:
type: string
required: true
- in: query
name: page
schema:
type: integer
example: 1
default: 1
- in: query
name: html
description: Convert the "description" field from markdown to HTML
schema:
type: boolean
example: true
responses:
'200':
description: A paginated list of the broadcasts created by a user.
headers:
Access-Control-Allow-Origin:
schema:
type: string
default: '''*'''
content:
application/json:
schema:
type: object
properties:
currentPage:
type: integer
example: 4
maxPerPage:
type: integer
example: 15
currentPageResults:
type: array
items:
$ref: '#/components/schemas/BroadcastByUser'
nbResults:
type: integer
example: 205194
previousPage:
type:
- integer
- 'null'
example: 3
nextPage:
type:
- integer
- 'null'
example: 5
nbPages:
type: integer
example: 13680
required:
- currentPage
- maxPerPage
- currentPageResults
- nbResults
- previousPage
- nextPage
- nbPages
examples:
default:
$ref: '#/components/examples/broadcasts-getBroadcastsCreatedByUser.json'
/api/broadcast/search:
get:
operationId: broadcastsSearch
summary: Search broadcasts
description: 'Search across recent official broadcasts.
'
tags:
- Broadcasts
security: []
parameters:
- in: query
name: page
description: Which page to fetch.
schema:
type: integer
default: 1
minimum: 1
maximum: 20
- in: query
name: q
description: Search term
schema:
type: string
responses:
'200':
description: Paginated top broadcast previews.
headers:
Access-Control-Allow-Origin:
schema:
type: string
default: '''*'''
content:
application/json:
schema:
type: object
properties:
currentPage:
type: integer
maxPerPage:
type: integer
currentPageResults:
type: array
items:
$ref: '#/components/schemas/BroadcastWithLastRound'
previousPage:
type:
- integer
- 'null'
nextPage:
type:
- integer
- 'null'
required:
- currentPage
- maxPerPage
- currentPageResults
- previousPage
- nextPage
examples:
default:
$ref: '#/components/examples/broadcasts-searchBroadcasts.json'
/broadcast/new:
post:
operationId: broadcastTourCreate
summary: Create a broadcast tournament
description: 'Create a new broadcast tournament to relay external games.
This endpoint accepts the same form data as the [web form](https://lichess.org/broadcast/new).
'
tags:
- Broadcasts
security:
- OAuth2:
- study:write
requestBody:
required: true
content:
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/BroadcastForm'
responses:
'200':
description: The broadcast tournament was successfully created.
headers:
Access-Control-Allow-Origin:
schema:
type: string
default: '''*'''
content:
application/json:
schema:
$ref: '#/components/schemas/BroadcastWithRounds'
examples:
default:
$ref: '#/components/examples/broadcasts-createBroadcastTournament.json'
'400':
description: The creation of the broadcast tournament failed.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/api/broadcast/{broadcastTournamentId}:
get:
operationId: broadcastTourGet
summary: Get a broadcast tournament
description: 'Get information about a broadcast tournament.
'
tags:
- Broadcasts
security:
- {}
- OAuth2:
- study:read
parameters:
- in: path
name: broadcastTournamentId
description: The broadcast tournament ID
required: true
schema:
type: string
minLength: 8
maxLength: 8
responses:
'200':
description: The information about the broadcast tournament.
content:
application/json:
schema:
$ref: '#/components/schemas/BroadcastWithRoundsAndFullGroup'
examples:
default:
$ref: '#/components/examples/broadcasts-getBroadcastTournament.json'
/broadcast/{broadcastTournamentId}/players:
get:
operationId: broadcastPlayersGet
summary: Get players of a broadcast
description: 'Get the list of players of a broadcast tournament, if available.
'
tags:
- Broadcasts
security: []
parameters:
- in: path
name: broadcastTournamentId
description: The broadcast tournament ID
required: true
schema:
type: string
minLength: 8
maxLength: 8
responses:
'200':
description: The broadcast players
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/BroadcastPlayerEntry'
examples:
default:
$ref: '#/components/examples/broadcasts-getPlayersOfBroadcastTournament.json'
/broadcast/{broadcastTournamentId}/players/{playerId}:
get:
operationId: broadcastPlayerGet
summary: Get a player of a broadcast
description: 'Get the details of a specific player and their games from a broadcast tournament.
'
tags:
- Broadcasts
security: []
parameters:
- in: path
name: broadcastTournamentId
description: The broadcast tournament ID
required: true
schema:
type: string
minLength: 8
maxLength: 8
- in: path
name: playerId
description: "The unique player ID within the broadcast. This is usually their fideId. \nIf the player does not have a fideId, it is their name. Consult the [list of players for the broadcast](#tag/broadcasts/GET/broadcast/{broadcastTournamentId}/players) for which ID to use.\n"
required: true
schema:
type: string
responses:
'200':
description: The broadcast player
content:
application/json:
schema:
type: object
$ref: '#/components/schemas/BroadcastPlayerEntryWithFideAndGames'
examples:
default:
$ref: '#/components/examples/broadcasts-getPlayer.json'
'404':
description: The player was not found
content:
application/json:
schema:
$ref: '#/components/schemas/NotFound'
/broadcast/{broadcastTournamentId}/teams/standings:
get:
operationId: broadcastTeamLeaderboardGet
summary: Get the team leaderboard of a broadcast
description: 'Get the team leaderboard of a broadcast tournament, if available.
'
tags:
- Broadcasts
security: []
parameters:
- in: path
name: broadcastTournamentId
description: The broadcast tournament ID
required: true
schema:
type: string
minLength: 8
maxLength: 8
responses:
'200':
description: The team leaderboard
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/BroadcastTeamLeaderboardEntry'
'404':
description: Broadcast tournament not found
/broadcast/{broadcastTournamentId}/edit:
post:
operationId: broadcastTourUpdate
summary: Update your broadcast tournament
description: '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.
'
tags:
- Broadcasts
security:
- OAuth2:
- study:write
parameters:
- in: path
name: broadcastTournamentId
description: The broadcast ID
required: true
schema:
type: string
minLength: 8
maxLength: 8
requestBody:
required: true
content:
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/BroadcastForm'
responses:
'200':
description: The broadcast tournament was successfully edited.
headers:
Access-Control-Allow-Origin:
schema:
type: string
default: '''*'''
content:
application/json:
schema:
$ref: '#/components/schemas/Ok'
examples:
default:
$ref: '#/components/examples/broadcasts-updateBroadcastTournament.json'
'400':
description: The broadcast tournament update failed.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/broadcast/{broadcastTournamentId}/new:
post:
operationId: broadcastRoundCreate
summary: Create a broadcast round
description: 'Create a new broadcast round to relay external games.
This endpoint accepts the same form data as the web form.
Choose one between `syncUrl`, `syncUrls`, `syncIds` and `syncUsers`, if it is missing, the broadcast needs to be fed by [pushing PGN to it](#tag/broadcasts/POST/api/broadcast/round/{broadcastRoundId}/push)
'
tags:
- Broadcasts
security:
- OAuth2:
- study:write
parameters:
- in: path
name: broadcastTournamentId
description: The broadcast tournament ID
required: true
schema:
type: string
minLength: 8
maxLength: 8
requestBody:
required: true
content:
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/BroadcastRoundForm'
responses:
'200':
description: The broadcast round was successfully created.
headers:
Access-Control-Allow-Origin:
schema:
type: string
default: '''*'''
content:
application/json:
schema:
$ref: '#/components/schemas/BroadcastRoundNew'
examples:
default:
$ref: '#/components/examples/broadcasts-createBroadcastRound.json'
'400':
description: The creation of the broadcast failed.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/api/broadcast/{broadcastTournamentSlug}/{broadcastRoundSlug}/{broadcastRoundId}:
get:
operationId: broadcastRoundGet
summary: Get a broadcast round
description: 'Get information about a broadcast round.
'
tags:
- Broadcasts
security: []
parameters:
- in: path
name: broadcastTournamentSlug
description: The broadcast tournament slug. Only used for SEO, the slug can be safely replaced by `-`. Only the `broadcastRoundId` is actually used.
required: true
schema:
type: string
- in: path
name: broadcastRoundSlug
description: The broadcast round slug. Only used for SEO, the slug can be safely replaced by `-`. Only the `broadcastRoundId` is actually used.
required: true
schema:
type: string
- in: path
name: broadcastRoundId
description: The broadcast Round ID
required: true
schema:
type: string
minLength: 8
maxLength: 8
responses:
'200':
description: The information about the broadcast round.
content:
application/json:
schema:
$ref: '#/components/schemas/BroadcastRound'
examples:
Regular Scoring:
$ref: '#/components/examples/broadcasts-getBroadcastRound.json'
Custom Scoring:
$ref: '#/components/examples/broadcasts-getBroadcastRoundWithCustomScoring.json'
/broadcast/round/{broadcastRoundId}/edit:
post:
operationId: broadcastRoundUpdate
summary: Update a broadcast round
description: 'Update information about a broadcast round.
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.
'
tags:
- Broadcasts
security:
- OAuth2:
- study:write
parameters:
- in: path
name: broadcastRoundId
description: The broadcast round ID
required: true
schema:
type: string
minLength: 8
maxLength: 8
- $ref: '#/components/parameters/PatchQuery'
requestBody:
required: true
content:
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/BroadcastRoundForm'
responses:
'200':
description: The broadcast round was successfully edited.
headers:
Access-Control-Allow-Origin:
schema:
type: string
default: '''*'''
content:
application/json:
schema:
$ref: '#/components/schemas/BroadcastRound'
examples:
default:
$ref: '#/components/examples/broadcasts-updateBroadcastRound.json'
'400':
description: The broadcast round update failed.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/api/broadcast/round/{broadcastRoundId}/reset:
post:
operationId: broadcastRoundReset
summary: Reset a broadcast round
description: 'Remove any games from the broadcast round and reset it to its initial state.
'
tags:
- Broadcasts
security:
- OAuth2:
- study:write
parameters:
- in: path
name: broadcastRoundId
description: The broadcast round ID
required: true
schema:
type: string
minLength: 8
maxLength: 8
responses:
'200':
description: The broadcast round was successfully reset.
headers:
Access-Control-Allow-Origin:
schema:
type: string
default: '''*'''
content:
application/json:
schema:
$ref: '#/components/schemas/Ok'
examples:
default:
$ref: '#/components/examples/broadcasts-resetBroadcastRound.json'
/api/broadcast/round/{broadcastRoundId}/push:
post:
operationId: broadcastPush
summary: Push PGN to a broadcast round
description: 'Update a broadcast with new PGN.
Only for broadcasts without a source URL.
'
tags:
- Broadcasts
security:
- OAuth2:
- study:write
parameters:
- in: path
name: broadcastRoundId
description: The broadcast round ID
required: true
schema:
type: string
minLength: 8
maxLength: 8
requestBody:
description: The PGN. It can contain up to 100 games, separated by a double new line.
required: true
content:
text/plain:
schema:
type: string
responses:
'200':
description: The broadcast was successfully updated.
headers:
Access-Control-Allow-Origin:
schema:
type: string
default: '''*'''
content:
application/json:
schema:
$ref: '#/components/schemas/BroadcastPgnPush'
examples:
default:
$ref: '#/components/examples/broadcasts-pushPgnToBroadcastRound.json'
'400':
description: There was a problem with the pushed PGN.
headers:
Access-Control-Allow-Origin:
schema:
type: string
default: '''*'''
content:
application/json:
schema:
properties:
error:
type: string
example:
error: Cannot parse moves
/api/stream/broadcast/round/{broadcastRoundId}.pgn:
get:
operationId: broadcastStreamRoundPgn
summary: Stream an ongoing broadcast round as PGN
description: 'This streaming endpoint first sends all games of a broadcast round 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 round.
This is the best way to get updates about an ongoing round. Streaming means no polling,
and no pollings means no latency, and minimum impact on the server.
'
tags:
- Broadcasts
security: []
parameters:
- in: path
name: broadcastRoundId
description: The broadcast round ID
required: true
schema:
type: string
minLength: 8
maxLength: 8
- in: query
name: clocks
description: 'Include clock comments in the PGN moves, when available.
Example: `2. exd5 { [%clk 1:01:27] } e5 { [%clk 1:01:28] }`
'
schema:
type: boolean
default: true
- in: query
name: comments
description: 'Include analysis comments in the PGN moves, when available.
Example: `12. Bxf6 { [%eval 0.23] }`
'
schema:
type: boolean
default: true
responses:
'200':
description: The PGN representation of the round games, then the PGNs of games as they are updated.
headers:
Access-Control-Allow-Origin:
schema:
type: string
default: '''*'''
content:
application/x-chess-pgn:
schema:
$ref: '#/components/schemas/StudyPgn'
examples:
pgn:
$ref: '#/components/examples/broadcasts-streamOngoingBroadcastRoundAsPgn.pgn'
/api/broadcast/round/{broadcastRoundId}.pgn:
get:
operationId: broadcastRoundPgn
summary: Export one round as PGN
description: '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 inefficient.
Instead, consider [streaming the tournament](#tag/broadcasts/GET/api/stream/broadcast/round/{broadcastRoundId}.pgn) to get
a new PGN every time a game is updated, in real-time.
'
tags:
- Broadcasts
security: []
parameters:
- in: path
name: broadcastRoundId
description: The round ID
required: true
schema:
type: string
minLength: 8
maxLength: 8
- in: query
name: clocks
description: 'Include clock comments in the PGN moves, when available.
Example: `2. exd5 { [%clk 1:01:27] } e5 { [%clk 1:01:28] }`
'
schema:
type: boolean
default: true
- in: query
name: comments
description: 'Include analysis comments in the PGN moves, when available.
Example: `12. Bxf6 { [%eval 0.23] }`
'
schema:
type: boolean
default: true
responses:
'200':
description: The PGN representation of the round.
headers:
Access-Control-Allow-Origin:
schema:
type: string
default: '''*'''
content:
application/x-chess-pgn:
schema:
$ref: '#/components/schemas/StudyPgn'
examples:
pgn:
$ref: '#/components/examples/broadcasts-exportOneRoundAsPgn.pgn'
/api/broadcast/{broadcastTournamentId}.pgn:
get:
operationId: broadcastAllRoundsPgn
summary:
# --- truncated at 32 KB (91 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/lichess/refs/heads/main/openapi/lichess-broadcasts-api-openapi.yml