Lichess O Auth API

Obtaining and revoking OAuth tokens. [Read about the Lichess API authentication methods and code examples](https://github.com/lichess-org/api/blob/master/example/README.md).

Operations 4

GET /oauth Request authorization code #
POST /api/token Obtain access token #
DELETE /api/token Revoke access token #
POST /api/token/test Test multiple OAuth tokens #

Work with this as data

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-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 Specification

lichess-oauth-api-openapi.yml Raw ↑
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:
  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
  examples:
    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
    oauth-testMultipleOauthTokens-request.txt:
      value: 'lip_jose,lip_badToken

        '
  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)