API Reference

Complete endpoint documentation for the ChessGrammar API v1.

Base URL: https://chessgrammar.com/api/v1

Access

The API is in Developer Preview. No authentication is required:

  • 30 requests/minute per IP
  • 3 game analyses/day per IP (position analysis is unlimited within the rate limit)

Need higher limits? Get in touch.


POST /extract

Analyze a position (FEN) or a game (PGN) for tactical patterns.

FEN Request

{
  "fen": "6k1/5p1p/4p3/4q3/3n4/2Q3P1/PP1N1P1P/6K1 b - - 3 37",
  "patterns": ["fork", "pin"],
  "depth": "l2",
  "with_sequence": true
}

Parameters:

ParameterTypeRequiredDefaultDescription
fenstringyesValid FEN string
patternsstring[]noall 10Filter by pattern names
depthstringno"l2""l1" (fast scan) or "l2" (forcing tree confirmation)
with_sequencebooleannofalseInclude forcing move sequences (~205ms/tactic). Ignored when depth="l1".

PGN Request

{
  "pgn": "1. e4 e5 2. Nf3 Nc6 3. Bc4 ...",
  "mode": "played",
  "patterns": ["fork", "discovered_attack"],
  "with_sequence": false
}

Parameters:

ParameterTypeRequiredDefaultDescription
pgnstringyesPGN string of a complete game
modestringno"played""played" (tactics actually executed) or "available" (all tactical opportunities)
patternsstring[]noall 10Filter by pattern names
depthstringno"l2""l1" or "l2"
with_sequencebooleannofalseInclude forcing move sequences. Ignored when depth="l1".

Response (FEN)

{
  "tactics": [
    {
      "pattern": "fork",
      "color": "black",
      "key_squares": ["e2"],
      "target_squares": ["g1", "c3"],
      "targets": [
        {"square": "g1", "piece": "K", "piece_name": "king", "color": "white"},
        {"square": "c3", "piece": "Q", "piece_name": "queen", "color": "white"}
      ],
      "gain": 700,
      "gain_confirmed": true,
      "is_mate": false,
      "trigger_move": "d4e2",
      "sequence": ["d4e2", "g1g2", "e2c3", "b2c3"],
      "fen": "6k1/5p1p/..."
    }
  ],
  "count": 1,
  "depth": "l2",
  "performance_ms": 48.2,
  "fen": "6k1/5p1p/..."
}

Response (PGN)

Same structure as FEN response, with additional fields per tactic:

FieldDescription
plyHalf-move number in the game
status"played" or "existing" (in mode: "played" only)

Tactic object

FieldTypeDescription
patternstringTactic type (fork, pin, skewer, discovered_attack, double_check, back_rank_mate, smothered_mate, deflection, interference, trapped_piece)
colorstringSide with the tactic (white or black)
trigger_movestringInitiating move in UCI format
key_squaresstring[]Critical squares involved
target_squaresstring[]Attacked/affected piece squares
targetsobject[]Detailed target info (square, piece, piece_name, color)
gainintegerMaterial gain in centipawns
gain_confirmedbooleantrue if confirmed via forcing tree (L2)
is_matebooleantrue if tactic leads to checkmate
sequencestring[] or nullForcing moves in UCI format (when with_sequence: true)
fenstringPosition FEN

Pattern names

Valid values for the patterns filter:

fork, pin, skewer, discovered_attack, double_check, back_rank_mate, smothered_mate, deflection, interference, trapped_piece


GET /health

Returns service status and engine info.

curl https://chessgrammar.com/api/v1/health
{
  "status": "ok",
  "engine_version": "2.5",
  "api_version": "1.0",
  "patterns": ["fork", "pin", "skewer", "discovered_attack", "double_check", "back_rank_mate", "smothered_mate", "deflection", "interference", "trapped_piece"],
  "patterns_count": 10
}

Errors

StatusBodyCause
400"error": "Missing 'fen' or 'pgn' field"No input provided
400"error": "Invalid FEN"Malformed FEN string
400"error": "Invalid PGN"Malformed PGN
400"error": "Invalid pattern: xyz"Unknown pattern name in filter
429"error": "Rate limit exceeded"More than 30 requests/minute
429"error": "Daily game analysis limit reached. Need more? Contact us."More than 3 game analyses/day