Powered by Stockfish 17 lite NNUE. Free API access is available; paid subscriptions are not enabled.

Documentation / Guides

Stockfish from Python

requests, async, and python-chess

Install nothing, call the API

import os, requests

API = "https://stockfishapi.com/v1"
H = {"Authorization": f"Bearer {os.environ['STOCKFISH_API_KEY']}"}

def evaluate(fen: str, depth: int = 14, lines: int = 1) -> dict:
    r = requests.post(f"{API}/eval", headers=H, json={"fen": fen, "depth": depth, "multipv": lines}, timeout=60)
    r.raise_for_status()
    return r.json()

pos = evaluate("r1bqkbnr/pppp1ppp/2n5/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq - 2 3", depth=16)
print(pos["bestmove"], pos["eval"], pos["cost_units"])

With python-chess

import chess
board = chess.Board()
board.push_san("e4"); board.push_san("e5")
best = evaluate(board.fen(), depth=12)["bestmove"]
board.push_uci(best)

Handle limits like a program, not a person

r = requests.post(f"{API}/eval", headers=H, json={"fen": fen, "depth": 24})
if r.status_code == 402:
    problem = r.json()
    if problem["next_action"] == "upgrade":
        print("Open this to upgrade:", problem["checkout"]["url"])
    elif problem["next_action"] == "raise_budget":
        ...
elif r.status_code == 429:
    time.sleep(int(r.headers["Retry-After"]))

Get a key: curl -X POST https://stockfishapi.com/v1/signup -H "Content-Type: application/json" -d '{"email":"you@example.com"}'

Get a key with one call: POST /v1/signup {"email":"you@example.com"}. Free plan, depth 14, 2,000 units a day.