Public / bot API

Call KiriChess from your own engine. The published promise is /api/v1 only. Issue a token on your profile; the raw secret is shown once.

Authentication

Send Authorization: Bearer kirichess_pat_… on every request. Scopes are exactly two. A token never carries admin or 2FA claims, even if the account does. Up to 10 tokens can be active at once. A token lasts 90 days unless you choose another life between 1 and 365 days, and you can revoke it sooner from the API tokens card on your profile page.

The value after kirichess_pat_ is 43 characters from the URL-safe base64 alphabet (A–Z, a–z, 0–9, hyphen, underscore), then 6 checksum characters. The checksum is the CRC-32 (IEEE) of those 43 characters, written as 6 base62 digits in the alphabet 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz and padded on the left with zeros. A secret scanner can reject a string that fails that check without calling this server.

  • read, identity, your games, finished replays, your open challenges, bot-pool ratings, bot seeks.
  • play, create unrated games and challenges, move and resign, and join bot-pool matchmaking over the hub. Play implies read at issue time.

Your engine runs in the process that calls this API. Browser origins other than this site stay blocked; CORS is not widened for this API.

curl https://api.kirichess.com/api/v1/account \
  -H "Authorization: Bearer $KIRICHESS_API_TOKEN"

Unrated HTTP, rated hub

POST /api/v1/games creates a solo/self-play game only, both seats are you, for exercising the engine end to end. It rejects an opponentId pointing at anyone else: matched play always goes through POST /api/v1/challenges or the bot pool. Rated measurement is opt-in: connect to the game hub with the same token and JoinQueue with an official preset (bounty1, burn1, steal1, steal2, burn2, steal3). That remaps onto bot:{preset} and never mixes with human Glicko.

The bot pool is a courtesy to honest bot authors, not a technical barrier: a script signed in with an account's own password looks identical to a browser at the queue and lands in the human pool. Playing the human pool from a script is against the rules, whichever credential it authenticates with.

curl -X POST https://api.kirichess.com/api/v1/games \
  -H "Authorization: Bearer $KIRICHESS_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"preset":"bounty1","opponentId":null,"rated":false}'

Live play

Connect to wss://api.kirichess.com/hubs/game. A bot authenticates the same way as everywhere else in this API: send Authorization: Bearer kirichess_pat_… on the connection request. The first-party site puts a short-lived session JWT in the access_token query, because a browser cannot set a header on a WebSocket handshake. The server still accepts a kirichess_pat_… token in that query. Do not put one there: it is written to Fly's proxy log, Cloudflare's request log, and Sentry's captured request URL.

Player methods: JoinQueue, SubmitMove, Resign, OfferDraw, RespondDraw and LeaveQueue. Events: MatchFound, MovePlayed, GameEnded, DrawOffered, DrawDeclined, OpponentDisconnected and OpponentReconnected. WatchChallenge and UnwatchChallenge subscribe this connection to a challenge you created; OfferRematch and AcceptRematch continue a finished game. JoinAsSpectator stays anonymous. A working loop is connect, JoinQueue, wait for MatchFound, then JoinGame(gameId) to get the current position and subscribe to that game's events before calling SubmitMove or reacting to MovePlayed; skipping JoinGame means no MovePlayed events ever arrive. Moves in a hub-matched game can also be posted over POST /api/v1/games/{id}/moves instead of the hub, if that is easier for your client.

Rate limits

  • Reads: 300 per minute per token (more generous than the human replay policy).
  • Creating games and challenges: 12 per minute per token, shared by both. A signed-in browser gets 12 game creates a minute and, separately, 10 challenge creates a minute.
  • Moves: same numbers as a human (60 burst / 30 per second). A rejected move can still flag a game; a key must not buy a faster clock.
  • Across every token on the account: 1800 requests a minute. One token's sustained move rate already sits at this ceiling.

Source

The server, engine and this site are Apache-2.0. Stockfish is a separate GPL-3.0 program; the board-move sounds are CC0 1.0. The name, wordmark and logo are not licensed; see NOTICE. The working repository is private. github.com/MichielGekiere/kirichess