# Protocol ![Fishnet sequence diagram](https://raw.githubusercontent.com/lichess-org/fishnet/master/doc/sequence-diagram.png) Client asks server: ```javascript POST https://lichess.org/fishnet/acquire { "fishnet": { "version": "2.3.4", "apikey": "XXX" } } ``` Response with work: ```javascript 202 OK { "work": { "type": "analysis", "id": "work_id", "nodes": { // node limit for each sf version "sf15": 1500000, "sf14": 2100000, "classical": 4050000 }, "timeout": 7000 // milliseconds per ply }, // or: // "work": { // "type": "move", // "id": "work_id", // "level": 5 // 1 to 8 // "clock": { // optional // "wtime": 18000, // time on white clock (centiseconds) // "btime": 18000, // time on black clock // "inc": 2, // fisher increment (seconds) // } // }, "game_id": "abcdefgh", // optional, can be empty string for bc "position": "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1", // start position (X-FEN) "variant": "standard", "moves": "e2e4 c7c5 c2c4 b8c6 g1e2 g8f6 b1c3 c6b4 g2g3 b4d3", // moves of the game (UCI) "skipPositions": [1, 4, 5] // 0 is the first position } ``` Response with no work found: ``` 204 No Content ``` Client runs Stockfish and sends the analysis to server. The client can optionally report progress to the server, by sending null for the pending moves in `analysis`. ```javascript POST https://lichess.org/fishnet/analysis/{work_id} { "fishnet": { "version": "2.3.4", "apikey": "XXX" }, "stockfish": { "flavor": "nnue" // or classical }, "analysis": [ { // first ply "pv": "e2e4 e7e5 g1f3 g8f6", "depth": 18, "score": { "cp": 24 }, "time": 1004, "nodes": 1686023, "nps": 1670251 }, { // second ply (1 was in skipPositions) "skipped": true }, // ... { // second last ply "pv": "b4d3", "depth": 127, "score": { "mate": 1 }, "time": 3, "nodes": 3691, "nps": 1230333 }, { // last ply "depth": 0, "score": { "mate": 0 } } ] } ``` Or the move: ```javascript POST https://lichess.org/fishnet/move/{work_id} { "fishnet": { "version": "2.3.4", "apikey": "XXX" }, "move": { "bestmove": "b7b8q" } } ``` Query parameters: - `?slow=true`: Do not acquire user requested analysis. Speed is not important for system requested analysis. - `?stop=true`: Submit result. Do not acquire next job. Accepted: ``` 204 No content ``` Accepted, with next job: ``` 202 Accepted [...] ``` ## Aborting jobs The client should send a request like the following, when shutting down instead of completing an analysis. The server can then immediately give the job to another client. ``` POST https://lichess.org/fishnet/abort/{work_id} { "fishnet": { "version": "2.3.4", "apikey": "XXX" } } ``` Response: ``` 204 No Content ``` Or abort not supported: ``` 404 Not found ``` ## Status Useful to monitor and react to queue status or spawn spot instances. ``` GET https://lichess.org/fishnet/status ``` ```javascript 200 OK { "analysis": { "user": { // User requested analysis (respond as soon as possible) "acquired": 93, // Number of jobs that are currently assigned to clients "queued": 1, // Number of jobs waiting to be assigned "oldest": 5 // Age in seconds of oldest job in queue }, "system": { // System requested analysis (for example spot check for cheat // screening, low priority, queue may build up during peak time // and should be cleared once a day) "acquired": 128, "queued": 14886, "oldest": 7539 } } } ``` Or queue monitoring is not supported (for example internal [lila-fishnet](https://github.com/ornicar/lila-fishnet)): ``` 404 Not found ``` ## Key validation ``` GET https://lichess.org/fishnet/key/XXX ``` Key valid: ``` 200 Ok ``` Key invalid/inactive: ``` 404 Not found ``` ## Prepared changes These experimental changes have already been implemented in the client, and future versions of the server might start using them. - Client version sent as header `User-Agent: fishnet--/`. - Key sent as header `Authorization: Bearer `. In the future the key validation endpoint may be deprecated in favor of a `GET /fishnet/key` request, a no-op to validate the header. - New optional `work.depth`. - New optional `work.multipv`, to get top _multipv_ scores and pvs at each depth. - Reject client until update or reconfiguration with status code: - 400 Bad Request (Update required due to protocol change) - 401 Unauthorized (Unknown key) - 403 Forbidden (Key disabled) - 406 Not Acceptable (Update required)