Chess position API preview. Photo in, FEN out.

Send a photo of a real chessboard and get the position back as FEN, with confidence, the squares the model doubts, the board’s orientation and a rendered board. The API is a preview: free, limited to 5 scans a day per account, and it may change without notice.

Photo of a wooden chess board mid-game, taken from above
Example response200
{
  "status": "completed",
  "fen": "r2q1rk1/2p2ppp/2np1N2/1pb1p1B1/p3P3/1B1P1Q1P/PPP2PP1/R4RK1 w - - 0 1",
  "unsure_squares": ["e4", "f6"],
  "orientation": { "view": "white" }
}

Get a key

Sign in to the web app, open Settings, and create a key under API access. An account has one key, and it is shown only once. An agent needs its user to create the key for it.

Scan a board

Post the photo as the request body, up to 10 MB, as JPEG, PNG, WebP or HEIC:

POST /api/v1/scans
curl -X POST https://app.snapthatpiece.com/api/v1/scans \
  -H "Authorization: Bearer $STP_KEY" \
  -H "Content-Type: image/jpeg" \
  --data-binary @board.jpg

The answer is 202 with the scan’s id. Scans run in the background and usually finish in seconds, so poll about once a second until status is completed or failed:

GET /api/v1/scans/{id}
curl https://app.snapthatpiece.com/api/v1/scans/$SCAN_ID \
  -H "Authorization: Bearer $STP_KEY"

What comes back

Example response
{
  "id": "0f1e2d3c-4b5a-6978-8796-a5b4c3d2e1f0",
  "status": "completed",
  "created_at": "2026-10-30T15:12:04+00:00",
  "completed_at": "2026-10-30T15:12:06+00:00",
  "fen": "r2q1rk1/2p2ppp/2np1N2/1pb1p1B1/p3P3/1B1P1Q1P/PPP2PP1/R4RK1 w - - 0 1",
  "confidence": { "board": 0.86, "mean": 0.61 },
  "unsure_squares": ["e4", "f6"],
  "unsure": true,
  "orientation": { "view": "white", "ambiguous": false },
  "piece_count": 29,
  "board_px_per_square": 82.5,
  "error": null,
  "links": {
    "self": "/api/v1/scans/0f1e2d3c-4b5a-6978-8796-a5b4c3d2e1f0",
    "board_svg": "/api/v1/scans/0f1e2d3c-4b5a-6978-8796-a5b4c3d2e1f0/board.svg"
  }
}
  • fen: the position, in full FEN. A photo doesn’t show whose turn it is, so treat the side to move, castling and en passant as placeholders.
  • confidence: the classifier’s probabilities from 0 to 1, over the occupied squares and over all 64. They are not an accuracy figure.
  • unsure_squares: squares read below the model’s usual confidence. Check these first, but errors can be elsewhere too.
  • unsure: true with two or more unsure squares. Have someone check the read.
  • orientation: the side to show the board from, which is the side the photo was taken from unless its owner changed it, and whether the model couldn’t tell which side is which.
  • If the account’s owner corrects a scan in the app, fen, unsure_squares and the rendered board follow the correction.
  • board_px_per_square: the board’s size in the photo. Under about 40, expect more errors.

Rendered board

GET /api/v1/scans/{id}/board.svg draws the read board from the scan’s orientation.view, with an amber dot on each unsure square. Add ?view=white or ?view=black to choose the side. During the preview, the board carries the Snap That Piece logo and name in its bottom right corner. Please leave them in place.

The example position drawn by the API, with amber dots on e4 and f6 and the Snap That Piece logo in the bottom right corner

Stockfish evaluations are not part of the preview.

Limits

  • 5 boards read a day per account, over a rolling 24 hours. A photo where no board is found doesn’t count, but only 15 tries are allowed in the same period, whatever their result.
  • GET /api/v1/usage says how many scans are left and when one comes back.
  • Over a limit, the answer is 429 with a Retry-After header, and an error code to branch on.

How results may be used

A result may be used to answer the person who asked for it. It may not be used to train or fine-tune models, to build a dataset, or be sold or redistributed. Photos sent through the API may be used to train our models, so only send photos you have the right to share. The full wording is in the Terms of Service.

Read your first board

Create a key in Settings and send a photo. 5 scans a day, free during the preview.