Every API here is available over the APIs.io API and to AI agents over MCP.
MCP server
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
Tools for apis
7 MCP tools reach this
find_apisBrowse and filter every API in the catalog.
get_api_artifactsOne API's artifacts, grouped by type.
get_openapiThe primary OpenAPI for this API.
find_similar_apisAPIs that look like this one.
apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
resolveTurn a domain, URL or GitHub org into the provider it belongs to.
find_cohortsEvery scored population of providers in the catalog.
All 92 tools →
Call it yourself
curl for this page
This API
curl "https://apis.io/api/v1/apis/lichess-bulk-pairings-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"
Discovery needs no key. Ratings and market analysis are Pro.
Get an API key
Free tier, no form to fill in. Signing in shares your email address with us — we
store it to create your key and to recognise you if you sign in with another
provider. See our Privacy Policy and
Terms.
A second provider on the same verified email joins the account you already have.
openapi: 3.2.0
info:
version: 2.0.144
title: Lichess.org API reference Bulk pairings 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!'
servers:
- url: https://lichess.org
- url: https://lichess.dev
- url: http://localhost:{port}
variables:
port:
default: '8080'
- url: http://l.org
tags:
- name: Bulk pairings
description: 'Create many games for other players.
These endpoints are intended for tournament organisers.'
paths:
/api/bulk-pairing:
get:
operationId: bulkPairingList
summary: View your bulk pairings
description: Get a list of bulk pairings you created.
tags:
- Bulk pairings
security:
- OAuth2:
- challenge:bulk
responses:
'200':
description: The list of bulk pairing the logged in user created.
headers:
Access-Control-Allow-Origin:
schema:
type: string
default: '''*'''
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/BulkPairing'
post:
operationId: bulkPairingCreate
summary: Create a bulk pairing
description: '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.'
tags:
- Bulk pairings
security:
- OAuth2:
- challenge:bulk
requestBody:
description: Parameters of the pairings
required: true
content:
application/x-www-form-urlencoded:
schema:
type: object
properties:
players:
type: string
description: '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:
type: integer
description: 'Clock initial time in seconds. Example: `600`
'
minimum: 0
maximum: 10800
clock.increment:
type: integer
description: 'Clock increment in seconds. Example: `2`
'
minimum: 0
maximum: 60
days:
type: integer
description: Days per turn. For correspondence games only.
enum:
- 1
- 2
- 3
- 5
- 7
- 10
- 14
pairAt:
type: integer
format: int64
description: '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:
type: integer
format: int64
description: '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:
type: boolean
description: Game is rated and impacts players ratings
default: false
variant:
$ref: '#/components/schemas/VariantKey'
fen:
$ref: '#/components/schemas/FromPositionFEN'
message:
type: string
description: '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.
'
default: 'Your game with {opponent} is ready: {game}.'
rules:
type: string
enum:
- noAbort
- noRematch
- noGiveTime
- noClaimWin
- noEarlyDraw
description: 'Extra game rules separated by commas.
Example: `noAbort,noRematch`
'
responses:
'200':
description: The bulk pairing has been successfully created.
headers:
Access-Control-Allow-Origin:
schema:
type: string
default: '''*'''
content:
application/json:
schema:
$ref: '#/components/schemas/BulkPairing'
'400':
description: The creation of the bulk pairings failed.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/api/bulk-pairing/{id}/start-clocks:
post:
operationId: bulkPairingStartClocks
summary: Manually start clocks
description: '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.'
tags:
- Bulk pairings
security:
- OAuth2:
- challenge:bulk
parameters:
- in: path
name: id
schema:
type: string
description: The ID of the bulk pairing
example: 5IrD6Gzz
required: true
responses:
'200':
description: The clocks of the games of a bulk pairing were successfully started.
headers:
Access-Control-Allow-Origin:
schema:
type: string
default: '''*'''
content:
application/json:
schema:
$ref: '#/components/schemas/Ok'
'404':
description: The bulk pairing was not found.
content:
application/json:
schema:
$ref: '#/components/schemas/NotFound'
/api/bulk-pairing/{id}:
get:
operationId: bulkPairingGet
summary: Show a bulk pairing
description: Get a single bulk pairing by its ID.
tags:
- Bulk pairings
security:
- OAuth2:
- challenge:bulk
parameters:
- in: path
name: id
schema:
type: string
description: The ID of the bulk pairing
example: 5IrD6Gzz
required: true
responses:
'200':
description: The bulk pairing.
headers:
Access-Control-Allow-Origin:
schema:
type: string
default: '''*'''
content:
application/json:
schema:
$ref: '#/components/schemas/BulkPairing'
'404':
description: The bulk pairing was not found.
content:
application/json:
schema:
$ref: '#/components/schemas/NotFound'
delete:
operationId: bulkPairingDelete
summary: Cancel a bulk pairing
description: '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.'
tags:
- Bulk pairings
security:
- OAuth2:
- challenge:bulk
parameters:
- in: path
name: id
schema:
type: string
description: The ID of the bulk pairing
example: 5IrD6Gzz
required: true
responses:
'200':
description: The bulk pairing was successfully deleted.
headers:
Access-Control-Allow-Origin:
schema:
type: string
default: '''*'''
content:
application/json:
schema:
$ref: '#/components/schemas/Ok'
'404':
description: The bulk pairing to delete was not found.
content:
application/json:
schema:
$ref: '#/components/schemas/NotFound'
/api/bulk-pairing/{id}/games:
get:
operationId: bulkPairingIdGamesGet
summary: Export games of a bulk pairing
description: Download games of a bulk in PGN or ndjson format, depending on the request `Accept` header.
tags:
- Bulk pairings
security:
- OAuth2:
- challenge:bulk
parameters:
- $ref: '#/components/parameters/AcceptPgnOrNdjson'
- in: path
name: id
schema:
type: string
description: The ID of the bulk pairing
example: 5IrD6Gzz
required: true
- in: query
name: moves
description: Include the PGN moves.
schema:
type: boolean
default: true
- in: query
name: pgnInJson
description: Include the full PGN within the JSON response, in a `pgn` field.
schema:
type: boolean
default: false
- in: query
name: tags
description: Include the PGN tags.
schema:
type: boolean
default: true
- in: query
name: clocks
description: '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.
'
schema:
type: boolean
default: false
- in: query
name: evals
description: '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.
'
schema:
type: boolean
default: false
- in: query
name: accuracy
description: 'Include [accuracy percent](https://lichess.org/page/accuracy) of each player, when available. Only available in JSON.
'
schema:
type: boolean
default: false
- in: query
name: opening
description: 'Include the opening name.
Example: `[Opening "King''s Gambit Accepted, King''s Knight Gambit"]`
'
schema:
type: boolean
default: false
- in: query
name: division
description: 'Plies which mark the beginning of the middlegame and endgame.
Only available in JSON
'
schema:
type: boolean
default: false
- in: query
name: literate
description: '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)`
'
schema:
type: boolean
default: false
responses:
'200':
description: The representation of the games.
headers:
Access-Control-Allow-Origin:
schema:
type: string
default: '''*'''
content:
application/x-chess-pgn:
schema:
$ref: '#/components/schemas/GamePgn'
application/x-ndjson:
schema:
$ref: '#/components/schemas/GameJson'
components:
schemas:
GameOpening:
type: object
properties:
eco:
type: string
name:
type: string
ply:
type: integer
required:
- eco
- name
- ply
GameColor:
type: string
enum:
- white
- black
Speed:
type: string
enum:
- ultraBullet
- bullet
- blitz
- rapid
- classical
- correspondence
GamePlayers:
type: object
properties:
white:
$ref: '#/components/schemas/GamePlayerUser'
black:
$ref: '#/components/schemas/GamePlayerUser'
required:
- white
- black
Error:
type: object
properties:
error:
type: string
description: The cause of the error.
required:
- error
example:
error: This request is invalid because [...]
GameStatusName:
type: string
enum:
- created
- started
- aborted
- mate
- resign
- stalemate
- timeout
- draw
- outoftime
- cheat
- noStart
- unknownFinish
- insufficientMaterialClaim
- variantEnd
BulkPairing:
type: object
properties:
id:
type: string
games:
type: array
items:
type: object
properties:
id:
type: string
black:
type: string
white:
type: string
variant:
$ref: '#/components/schemas/VariantKey'
clock:
$ref: '#/components/schemas/Clock'
pairAt:
type: integer
pairedAt:
type:
- integer
- 'null'
rated:
type: boolean
startClocksAt:
type: integer
scheduledAt:
type: integer
required:
- id
- games
- variant
- clock
- pairAt
- pairedAt
- rated
- startClocksAt
- scheduledAt
example:
id: RVAcwgg7
games:
- id: NKop9IyD
black: lizen1
white: thibault
- id: KT8374ut
black: lizen3
white: lizen2
- id: wInQr8Sk
black: lizen5
white: lizen4
variant: standard
clock:
increment: 0
limit: 300
pairAt: 1612289869919
pairedAt: null
rated: false
startClocksAt: 1612200422971
scheduledAt: 1612203514628
VariantKey:
type: string
enum:
- standard
- chess960
- crazyhouse
- antichess
- atomic
- horde
- kingOfTheHill
- racingKings
- threeCheck
- fromPosition
example: standard
default: standard
Clock:
type: object
properties:
limit:
type: integer
increment:
type: integer
required:
- limit
- increment
PatronColor:
type: integer
description: 'Players can choose a color for their Patron wings.
See [here for the color mappings](https://github.com/lichess-org/lila/blob/master/ui/lib/css/abstract/_patron-colors.scss).
The presence of this field indicates the player is an active Patron.
'
minimum: 1
maximum: 10
GamePgn:
type: string
example: '[Event "Rated Blitz game"]
[Site "https://lichess.org/fY44h4OY"]
[Date "2018.03.29"]
[Round "-"]
[White "pveldman"]
[Black "thibault"]
[Result "1-0"]
[UTCDate "2018.03.29"]
[UTCTime "01:38:15"]
[WhiteElo "1610"]
[BlackElo "1601"]
[WhiteRatingDiff "+10"]
[BlackRatingDiff "-10"]
[Variant "Standard"]
[TimeControl "180+0"]
[ECO "C62"]
[Opening "Ruy Lopez: Steinitz Defense"]
[Termination "Normal"]
1. e4 { [%clk 0:03:00] } e5 { [%clk 0:03:00] } 2. Nf3 { [%clk 0:02:59] } Nc6 { [%clk 0:02:58] } 3. Bb5 { [%clk 0:02:57] } d6 { [%clk 0:02:55] } 4. h3 { [%clk 0:02:54] } Nf6 { [%clk 0:02:52] } 5. Bxc6+ { [%clk 0:02:52] } bxc6 { [%clk 0:02:49] } 6. d3 { [%clk 0:02:51] } Be7 { [%clk 0:02:46] } 7. O-O { [%clk 0:02:47] } O-O { [%clk 0:02:45] } 8. b3 { [%clk 0:02:45] } d5 { [%clk 0:02:45] } 9. exd5 { [%clk 0:02:33] } cxd5 { [%clk 0:02:40] } 10. Nxe5 { [%clk 0:02:31] } Qd6 { [%clk 0:02:38] } 1-0
'
Title:
type: string
enum:
- GM
- WGM
- IM
- WIM
- FM
- WFM
- NM
- CM
- WCM
- WNM
- LM
- BOT
description: only appears if the user is a titled player or a bot user
Flair:
type: string
description: See [available flair list and images](https://github.com/lichess-org/lila/tree/master/public/flair)
GameMoveAnalysis:
type: object
properties:
eval:
type: integer
description: Evaluation in centipawns
mate:
type: integer
description: Number of moves until forced mate
best:
type: string
example: c2c3
description: Best move in UCI notation (only if played move was inaccurate)
variation:
type: string
example: c3 Nc6 d4 Qb6 Be2 Nge7 Na3 cxd4 cxd4 Nf5
description: Best variation in SAN notation (only if played move was inaccurate)
judgment:
type: object
description: Judgment annotation (only if played move was inaccurate)
properties:
name:
type: string
enum:
- Inaccuracy
- Mistake
- Blunder
comment:
type: string
example: Blunder. Nxg6 was best.
FromPositionFEN:
type: string
description: Custom initial position (in X-FEN). Variant must be standard, fromPosition, or chess960 (if a valid 960 starting position), and the game cannot be rated.
default: rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1
LightUser:
type: object
properties:
id:
type: string
name:
type: string
flair:
$ref: '#/components/schemas/Flair'
title:
$ref: '#/components/schemas/Title'
patron:
$ref: '#/components/schemas/Patron'
patronColor:
$ref: '#/components/schemas/PatronColor'
required:
- id
- name
NotFound:
properties:
error:
type: string
required:
- error
example:
error: Not found.
GamePlayerUser:
type: object
properties:
user:
$ref: '#/components/schemas/LightUser'
rating:
type: integer
ratingDiff:
type: integer
name:
type: string
provisional:
type: boolean
aiLevel:
type: integer
analysis:
type: object
properties:
inaccuracy:
type: integer
mistake:
type: integer
blunder:
type: integer
acpl:
type: integer
accuracy:
type: integer
required:
- inaccuracy
- mistake
- blunder
- acpl
team:
type: string
required:
- user
- rating
Patron:
type: boolean
deprecated: true
description: 'Use patronColor value instead to determine if player is a patron.
'
GameJson:
type: object
properties:
id:
type: string
rated:
type: boolean
variant:
$ref: '#/components/schemas/VariantKey'
speed:
$ref: '#/components/schemas/Speed'
perf:
type: string
createdAt:
type: integer
format: int64
lastMoveAt:
type: integer
format: int64
status:
$ref: '#/components/schemas/GameStatusName'
source:
type: string
players:
$ref: '#/components/schemas/GamePlayers'
initialFen:
type: string
winner:
$ref: '#/components/schemas/GameColor'
opening:
$ref: '#/components/schemas/GameOpening'
moves:
type: string
pgn:
type: string
daysPerTurn:
type: integer
analysis:
type: array
items:
$ref: '#/components/schemas/GameMoveAnalysis'
tournament:
type: string
swiss:
type: string
clock:
type: object
properties:
initial:
type: integer
increment:
type: integer
totalTime:
type: integer
required:
- initial
- increment
- totalTime
clocks:
type: array
items:
type: integer
division:
type: object
properties:
middle:
type: integer
description: Ply at which the middlegame begins
end:
type: integer
description: Ply at which the endgame begins
required: []
required:
- id
- rated
- variant
- speed
- perf
- createdAt
- lastMoveAt
- status
- players
Ok:
properties:
ok:
type: boolean
required:
- ok
parameters:
AcceptPgnOrNdjson:
in: header
name: Accept
description: 'Specify the desired response format.
Use `application/x-chess-pgn` to get the games in PGN format.
Use `application/x-ndjson` to get the games in ndjson format. [Read about ndjson here](#description/streaming-with-nd-json) and how you can parse it in Javascript.
'
schema:
type: string
enum:
- application/x-chess-pgn
- application/x-ndjson
default: application/x-chess-pgn
securitySchemes:
OAuth2:
type: oauth2
description: 'Read [the introduction for how to make authenticated requests](#description/authentication).
'
flows:
authorizationCode:
authorizationUrl: https://lichess.org/oauth
tokenUrl: https://lichess.org/api/token
scopes:
preference:read: Read your preferences
preference:write: Write your preferences
email:read: Read your email address
engine:read: Read your external engines
engine:write: Create, update, delete your external engines
challenge:read: Read incoming challenges
challenge:write: Create, accept, decline challenges
challenge:bulk: Create, delete, query bulk pairings
study:read: Read private studies and broadcasts
study:write: Create, update, delete studies and broadcasts
tournament:write: Create tournaments
racer:write: Create and join puzzle races
puzzle:read: Read puzzle activity
puzzle:write: Write puzzle activity
team:read: Read private team information
team:write: Join, leave teams
team:lead: Manage teams (kick members, send PMs)
follow:read: Read followed players
follow:write: Follow and unfollow other players
msg:write: Send private messages to other players
board:play: Play with the Board API
bot:play: Play with the Bot API. Only for [Bot accounts](#tag/bot/POST/api/bot/account/upgrade)
web:mod: Use moderator tools (within the bounds of your permissions)