I'll stream position analysis to You

without exhausting your CPU.

Up to 80 MNPS Stockfish Logo Stockfish 16.1 NNUE calculation power @32 vCores / 128 GB DDR5


POST https://chess-api.com/v1

WEBSOCKET wss://chess-api.com/v1

// Post FEN position:
    fen: '8/1P1R4/n1r2B2/3Pp3/1k4P1/6K1/Bppr1P2/2q5 w - - 0 1',

// ... or text input with the list of moves:
    input: '<div ...',

// You can also provide custom options:
    fen: '8/1P1R4/n1r2B2/3Pp3/1k4P1/6K1/Bppr1P2/2q5 w - - 0 1',
    variants: 1, // max: 5, default: 1,
    depth: 12, // max: 18, default: 12,
    maxThinkingTime: 50, // max: 100, default: 50 (ms),
    searchmoves: '', // evaluate specific moves only, ex. 'd2d4 e2e4',

❗Greater depth and more thinking time is available for project supporters.


    text: "Move b7 → b8 (b8=Q+): [-11.62]. Black is winning. Depth 12.",
    eval: -11.62,
    move: "b7b8q",
    fen: "8/1P1R4/n1r2B2/3Pp3/1k4P1/6K1/Bppr1P2/2q5 w - - 0 1",
    depth: 12,
    winChance: 1.3672836783305158,
    continuationArr: (5) ['a6c5', 'b7b8q', 'c6b6', 'b8b6', 'b4a3'],
    mate: null,
    centipawns: "-1162",
    san: "b8=Q+",
    lan: "b7b8q",
    turn: "w",
    color: "w",
    piece: "p",
    flags: "np",
    isCapture: false,
    isCastling: false,
    isPromotion: true,
    from: "b7",
    to: "b8",
    fromNumeric: "27",
    toNumeric: "28",

    taskId: "0k1pkg83g",
    time: 10677,
    type: "move"

Easy as 🦆:

You can try following scripts directly in your browser's console.

POST request

Performing a POST request is a simple way to receive the evaluation. However, it is less reactive than WS since server needs to "get" to the requested depth until it sends back the response.

// 1. Create a handy function for sending requests:
async function postChessApi(data = {}) {
    const response = await fetch("https://chess-api.com/v1", {
        method: "POST",
        headers: {
            "Content-Type": "application/json"
        body: JSON.stringify(data),
    return response.json();

// 2. Execute:
postChessApi({ fen: "8/1P1R4/n1r2B2/3Pp3/1k4P1/6K1/Bppr1P2/2q5 w - - 0 1" }).then((data) => {

// 3. You can provide text/html input to parse:
postChessApi({ input: document.querySelector('.moves-list').outerHTML }).then((data) => {


WebSocket connetion allows you to receive moves in progressive manner.

// 1. Open WebSocket connection:
ws = new WebSocket('wss://chess-api.com/v1');

// 2. Register callback to Log every incomming message in the console:
ws.onmessage = (event) => {
    const chessApiMessage = JSON.parse(event.data);

// 3. After connection is estabilished, send me a message:
    fen: '8/1P1R4/n1r2B2/3Pp3/1k4P1/6K1/Bppr1P2/2q5 w - - 0 1',
    variants: 3

// 4. You can also ask me to figure out position myself by sending text or HTML with moves list. My parsers will try to do their best.
    input: `<div ...`,
    variants: 3

Response fields:


Response types can be categorized as "move," "bestmove," or "info." Messages of type "move" are delivered progressively, indicating that the engine has identified a promising move at a given depth. The final message, denoted as "bestmove," represents the optimal move proposed among those identified. Additionally, "info" messages may include supplementary details such as status updates or error notifications.

type: 'bestmove'


Position evaluation. Negative value means that black is winning.

eval: -14.54


The depth at which the move was discovered is significant, as higher depths typically correlate with greater accuracy. For context, a depth of 12 corresponds to approximately 2350 FIDE elo, akin to the level of International Masters like Eric Rosen or Levy Rozman. A depth of 18 equates to around 2750 FIDE elo, reflective of the skill level of Grandmaster Hikaru Nakamura. Furthermore, a depth of 20 corresponds to approximately 2850 FIDE elo, indicative of the caliber of Grandmaster Magnus Carlsen.

depth: 12


Textual description of data.

text: 'Move b7 → b8 (b8=Q+): [-10.97]. Black is winning.'


Winning chance: value 50 (50%) means that position is equal. Over 50 - white is winning. Below 50 - black is winning. This is calculated using Lichess formula (Win% = 50 + 50 * (2 / (1 + exp(-0.00368208 * centipawns)) - 1)). Values are similar to what evaluation bar shows on most of chess websites.

winChance: 52.3321234425677


Forced mate sequence detected (number shows how many moves have to be played to mate opponent's king). Negative numbers concern black pieces.

mate: -12


Short algebraic notation of move.

san: 'b8=R+'


Array of next moves to be played in suggested variant.


.from / .to / .fromNumeric / .toNumeric

Move coordinations on the board. Might be handy to easily highlight moves on the board, draw arrows etc.

from: "b7", to: "b8", fromNumeric: "27", toNumeric: "28"


Information about captured piece (if any). Letters stands for piece name (r - rook, n - knight, q - queen an so on)

captured: 'r'


Current player's turn. Values: 'w' or 'b'.

turn: 'w'


Piece type (r - rook, n - knight, q - queen an so on)

piece: 'p'


Task (calculation) identifier. This can be set by attaching "taskId" field in your message. May be used to pair responses with request. Generate with random function like Math.rand().

taskId: '18lplzhja'


If move is promotion, piece symbol will be here (r / n / b / q)

promotion: 'q'


True or false - whether move is castling.

castling: true


Whether move is capture. True or false.

capture: true


Contains one or more of the string values: n - a non-capture / b - a pawn push of two squares / e - an en passant capture / c - a standard capture / p - a promotion / k - kingside castling / q - queenside castling.

flags: k

About the project

Chess-API gives an easy remote access to the calculation power of Stockfish 16.1 Chess Engine.

It was made to help people creating cool chess learning tools, browser extensions and more.

You can easily integrate it with your front-end JavaScript using Fetch API or WebSockets.

Created by Chris@PRONODE_SOFTWARE.

Chess API wouldn't be done without those wonderful libraries: