POST /v1/recognize
Request fields, response shape and examples for the recognize endpoint. Returns the FEN, per-square confidence, orientation and every board found in an image.
Reads the chessboards in one image. Authenticate with an API key. The body is multipart/form-data.
curl https://api.chessglance.com/v1/recognize \
-H "X-API-Key: $API_KEY" \
-F image=@board.png \
-F orientation=autoconst form = new FormData();
form.append('image', file); // a File or Blob
form.append('orientation', 'auto');
const response = await fetch('https://api.chessglance.com/v1/recognize', {
method: 'POST',
headers: { 'X-API-Key': process.env.API_KEY },
body: form,
});
if (!response.ok) throw new Error((await response.json()).error);
const { fen, diagnostics } = await response.json();
console.log(fen, diagnostics.confidence.uncertain_squares);import os
import requests
response = requests.post(
"https://api.chessglance.com/v1/recognize",
headers={"X-API-Key": os.environ["API_KEY"]},
files={"image": open("board.png", "rb")},
data={"orientation": "auto"},
timeout=60,
)
response.raise_for_status()
result = response.json()
print(result["fen"], result["diagnostics"]["confidence"]["uncertain_squares"])Request
| Field | Type | Description |
|---|---|---|
image |
file, required | PNG, JPEG or WebP. At most 12 MB and 40 megapixels. Any image/* content type is accepted; files that cannot be decoded return 400. |
orientation |
auto | white | black |
Which side is at the bottom of the image. Default auto, detected from the position. |
sideToMove |
w | b |
Written into the FEN. Default w. Not readable from an image. |
castling |
string | - or up to four of KQkq. Default -. |
ep |
string | - or an en-passant square such as e3. Default -. |
halfmove |
integer | Halfmove clock. Default 0. |
fullmove |
integer | Fullmove number. Default 1. |
maxBoards |
integer | Most boards to return from one image, 1 to 12. Default 6. |
bbox |
x,y,width,height |
Pixel box of one board. Skips board detection and reads exactly that region. |
noRepair |
true |
Return the raw per-square reading without the chess-rule repair. Default off; leave it off unless you are debugging. |
Invalid values for orientation, sideToMove, castling and ep are replaced by their defaults rather than rejected.
Response
200 OK with a JSON body. Without bbox, the top-level fields describe the best board, and boards lists every board found, best first.
{
"fen": "r1bqkbnr/pppp1ppp/2n5/4p3/2B1P3/5N2/PPPP1PPP/RNBQK2R w - - 0 1",
"board_fen": "r1bqkbnr/pppp1ppp/2n5/4p3/2B1P3/5N2/PPPP1PPP/RNBQK2R",
"labels": ["r", ".", "b", "q", "k", "b", "n", "r", "...56 more, a8 to h1"],
"candidate": { "bbox": [120, 80, 640, 640], "score": 0.96, "source": "checker" },
"diagnostics": {
"confidence": { "mean_confidence": 0.9987, "min_confidence": 0.93, "uncertain_squares": 0, "weakest_piece": 0.97 },
"orientation": "white",
"orientation_margin": 41.2,
"crop": { "...": "internal crop-refinement details; may change" },
"detected_boards": [ { "bbox": [120, 80, 640, 640], "score": 0.96, "source": "checker" } ]
},
"boards": [ { "fen": "…", "board_fen": "…", "labels": ["…"], "candidate": {}, "diagnostics": {} } ],
"requestId": "4b2c5e1a-8d0f-4f1e-9a53-0b6c2f7d1a90",
"elapsedMs": 380,
"model": { "path": "…", "sha256": "145a003e38bb0d34", "bytes": 8291342 },
"quota": { "limit": 10000, "used": 1250, "remaining": 8750, "resetAt": "2026-11-01T00:00:00.000Z" }
}
Values above are an example; real numbers differ.
Fields
| Field | Description |
|---|---|
fen |
Full six-field FEN, always written from White’s side. Placement comes from the image; the other five fields come from your request. |
board_fen |
Just the piece-placement field. |
labels |
64 entries from a8 to h1, . for an empty square, FEN letters for pieces. |
candidate |
Where the board was found: bbox as [x, y, width, height] in image pixels, plus localization scores. |
diagnostics.confidence |
mean_confidence, min_confidence (0 to 1), uncertain_squares (squares whose chosen label has under 60% probability) and weakest_piece (the least certain occupied square). |
diagnostics.orientation |
white or black: the side found at the bottom of the image. |
diagnostics.orientation_margin |
How decisive the orientation call was. Below 10 is uncertain. Only present when orientation=auto. |
boards |
Every board found, same shape as the top level. Not present when you pass bbox. |
requestId |
Also sent as the X-Request-Id header. Quote it in support requests. |
elapsedMs |
Server time for this request. |
model |
Which recognizer answered: a short SHA-256 of the model files and their size. |
quota |
Your plan’s usage after this request. |
Using confidence
Treat uncertain_squares > 0 as “show a person”. The recognizer would rather flag a square than invent a piece, and chess-rule repair guarantees one king per side, sane pawn ranks and legal material, so a flagged board is usually one or two squares off, not scrambled.
Headers
| Header | Meaning |
|---|---|
X-Request-Id |
The same value as requestId in the body. |
X-RateLimit-Limit |
Requests allowed in your plan’s window. |
X-RateLimit-Remaining |
Requests left in the window. |
X-RateLimit-Reset |
When the window resets, as an ISO 8601 UTC timestamp. |
Errors are documented on the errors and limits page.