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:lichess-oauth-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 OAuth 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: OAuth
description: 'Obtaining and revoking OAuth tokens.
Read about the Lichess API authentication methods and code examples.'
paths:
/oauth:
get:
operationId: oauth
summary: Request authorization code
tags:
- OAuth
security: []
description: '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.'
parameters:
- in: query
name: response_type
description: Must be `code`.
required: true
schema:
type: string
const: code
- in: query
name: client_id
description: Arbitrary identifier that uniquely identifies your application.
example: example.com
required: true
schema:
type: string
- in: query
name: redirect_uri
description: The absolute URL that the user should be redirected to with the authorization result.
required: true
schema:
type: string
- in: query
name: code_challenge_method
description: Must be `S256`.
required: true
schema:
type: string
const: S256
- in: query
name: code_challenge
description: Compute `BASE64URL(SHA256(code_verifier))`.
required: true
schema:
type: string
- in: query
name: scope
description: Space separated list of requested OAuth scopes, if any.
schema:
type: string
- in: query
name: username
description: Hint that you want the user to log in with a specific Lichess username.
schema:
type: string
- in: query
name: state
description: Arbitrary state that will be returned verbatim with the authorization result.
schema:
type: string
responses:
'200':
description: Authorization prompt will be displayed to the user.
/api/token:
post:
operationId: apiToken
summary: Obtain access token
tags:
- OAuth
security: []
description: OAuth2 token endpoint. Exchanges an authorization code for an access token.
requestBody:
required: true
content:
application/x-www-form-urlencoded:
schema:
type: object
properties:
grant_type:
type: string
example: authorization_code
const: authorization_code
code:
type: string
example: liu_iS1uOZg99Htmo58ex2jKgYziUfzsnAl0
description: The authorization code that was sent in the `code` parameter to your `redirect_uri`.
code_verifier:
type: string
example: Ry1rbGdOMTQtUjhOc0lmTnFKak1LTHV0NjlRMll2aXYtTThkQnlJRkRpaGwyQjh0ZDNFdzFPSG9KUlY4M1NrRzJ5ZHhUdjVZR08zLTZOT3dCN2xLfjZOXzU2WHk4SENP
description: A `code_challenge` was used to request the authorization code. This must be the `code_verifier` it was derived from.
redirect_uri:
type: string
example: http://example.com/
description: Must match the `redirect_uri` used to request the authorization code.
client_id:
type: string
example: example.com
description: Must match the `client_id` used to request the authorization code.
responses:
'200':
description: Access token successfully obtained.
headers:
Access-Control-Allow-Origin:
schema:
type: string
default: '''*'''
content:
application/json:
schema:
properties:
token_type:
type: string
example: Bearer
access_token:
type: string
example: lio_EXAMPLE_TOKEN_REDACTED_FOR_SECRET_SCAN
expires_in:
type: integer
example: 31536000
required:
- token_type
- access_token
- expires_in
'400':
description: Failed to obtain access token.
headers:
Access-Control-Allow-Origin:
schema:
type: string
default: '''*'''
content:
application/json:
schema:
$ref: '#/components/schemas/OAuthError'
delete:
operationId: apiTokenDelete
summary: Revoke access token
description: Revokes the access token sent as Bearer for this request.
tags:
- OAuth
security:
- OAuth2: []
responses:
'204':
description: Access token revoked.
headers:
Access-Control-Allow-Origin:
schema:
type: string
default: '''*'''
/api/token/test:
post:
operationId: tokenTest
summary: Test multiple OAuth tokens
description: '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.'
tags:
- OAuth
security: []
requestBody:
description: OAuth tokens separated by commas. Up to 1000.
required: true
content:
text/plain:
schema:
type: string
examples:
body:
$ref: '#/components/examples/oauth-testMultipleOauthTokens-request.txt'
responses:
'200':
description: The representation of the OAuth tokens.
content:
application/json:
schema:
type: object
additionalProperties:
x-additionalPropertiesName: token
oneOf:
- type: object
properties:
userId:
type: string
scopes:
type: string
description: Comma-separated list of scopes. Empty string if the token has no scopes.
expires:
type:
- integer
- 'null'
description: Unix-timestamp in milliseconds or null if the token never expires.
- type: 'null'
examples:
default:
$ref: '#/components/examples/oauth-testMultipleOauthTokens.json'
components:
examples:
oauth-testMultipleOauthTokens-request.txt:
value: 'lip_jose,lip_badToken
'
oauth-testMultipleOauthTokens.json:
value:
lip_jose:
userId: jose
scopes: preference:read,preference:write,email:read,challenge:read,challenge:write,challenge:bulk,study:read,study:write,tournament:write,racer:write,puzzle:read,puzzle:write,team:read,team:write,team:lead,follow:read,follow:write,msg:write,board:play,bot:play,engine:read,engine:write,web:mod
expires: null
lip_badToken: null
schemas:
OAuthError:
type: object
properties:
error:
type: string
description: The cause of the error.
error_description:
type: string
description: The reason why the request was rejected.
required:
- error
example:
error: invalid_grant
error_description: hash of code_verifier does not match code_challenge
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)
x-provenance:
method: harvested
publisher: Lichess
source: https://lichess.org/openapi.yaml
note: split by refine-openapis from the provider's own published document, verified by fetch (openapi/_original/*.fetch.json);
stamped by stamp-openapi-provenance.py (roadmap#793)