API contract

This annex is generated from the source code (go run ./cmd/openapi-gen; see openapi.yaml at the repository root for the full contract, schemas included): do not edit it directly, the next generation would overwrite any change. Each family groups the POST /v1/<family>.<method> methods the daemon exposes (see Headless mode (server)), with their response shape (JSON, or NDJSON for a streamed list) and, where it exists, a note of the optional Idempotency-Key header.

across
  POST /v1/across.analysesLoadByIds             JSON
  POST /v1/across.clubRanking                   JSON
  POST /v1/across.collectionPositions           NDJSON
  POST /v1/across.collectionsList               NDJSON
  POST /v1/across.commentsByZobrist             NDJSON
  POST /v1/across.matchMovePositions            NDJSON
  POST /v1/across.matchesGet                    JSON
  POST /v1/across.matchesList                   NDJSON
  POST /v1/across.playerTable                   JSON
  POST /v1/across.positionElsewhere             JSON
  POST /v1/across.searchFind                    NDJSON
  POST /v1/across.statsCompute                  JSON
  POST /v1/across.transferPull                  custom
analyses
  POST /v1/analyses.delete                      JSON
  POST /v1/analyses.load                        JSON
  POST /v1/analyses.loadByIds                   JSON
  POST /v1/analyses.queueStatus                 custom
  POST /v1/analyses.repair                      JSON
  POST /v1/analyses.save                        JSON
anki
  POST /v1/anki.buryCard                        JSON
  POST /v1/anki.createDeck                      JSON
  POST /v1/anki.createStudyDeck                 JSON
  POST /v1/anki.deckPositionCount               JSON
  POST /v1/anki.deckPositionIds                 JSON
  POST /v1/anki.deckPositions                   NDJSON
  POST /v1/anki.deckStats                       JSON
  POST /v1/anki.deleteDeck                      JSON
  POST /v1/anki.exportApkg                      custom
  POST /v1/anki.filteredPositionCount           JSON
  POST /v1/anki.filteredPositionIds             JSON
  POST /v1/anki.forecast                        JSON
  POST /v1/anki.indexOfDeckPosition             JSON
  POST /v1/anki.indexOfFilteredPosition         JSON
  POST /v1/anki.linkedCard                      JSON
  POST /v1/anki.listDecks                       NDJSON
  POST /v1/anki.nextCard                        JSON
  POST /v1/anki.removeCard                      JSON
  POST /v1/anki.resetDeck                       JSON
  POST /v1/anki.retention                       JSON
  POST /v1/anki.reviewCard                      JSON  (Idempotency-Key)
  POST /v1/anki.reviewLog                       NDJSON
  POST /v1/anki.reviewsByGameType               JSON
  POST /v1/anki.suspendCard                     JSON
  POST /v1/anki.sync                            JSON
  POST /v1/anki.syncWithPositions               JSON
  POST /v1/anki.undoReview                      JSON  (Idempotency-Key)
  POST /v1/anki.updateDeck                      JSON
  POST /v1/anki.updateDeckParams                JSON
collections
  POST /v1/collections.addPosition              JSON
  POST /v1/collections.addPositions             JSON
  POST /v1/collections.collectionsOf            NDJSON
  POST /v1/collections.copyPosition             JSON
  POST /v1/collections.countPositions           JSON
  POST /v1/collections.create                   JSON  (Idempotency-Key)
  POST /v1/collections.delete                   JSON
  POST /v1/collections.evaluate                 JSON
  POST /v1/collections.freeze                   JSON
  POST /v1/collections.get                      JSON
  POST /v1/collections.indexOfPosition          JSON
  POST /v1/collections.list                     NDJSON
  POST /v1/collections.movePosition             JSON
  POST /v1/collections.positionIds              JSON
  POST /v1/collections.positionIndexMap         JSON
  POST /v1/collections.positions                NDJSON
  POST /v1/collections.removePosition           JSON
  POST /v1/collections.removePositions          JSON
  POST /v1/collections.reorder                  JSON
  POST /v1/collections.reorderPositions         JSON
  POST /v1/collections.setFilter                JSON
  POST /v1/collections.suggest                  JSON
  POST /v1/collections.update                   JSON
comments
  POST /v1/comments.add                         JSON
  POST /v1/comments.byPosition                  NDJSON
  POST /v1/comments.delete                      JSON
  POST /v1/comments.deleteForPosition           JSON
  POST /v1/comments.listAll                     NDJSON
  POST /v1/comments.search                      NDJSON
  POST /v1/comments.tags                        JSON
  POST /v1/comments.text                        JSON
  POST /v1/comments.update                      JSON
directions
  POST /v1/directions.addNote                   JSON  (Idempotency-Key)  (If-Match)
  POST /v1/directions.addPair                   JSON  (Idempotency-Key)  (If-Match)
  POST /v1/directions.addParticipant            JSON  (Idempotency-Key)  (If-Match)
  POST /v1/directions.attachMatch               JSON  (Idempotency-Key)  (If-Match)
  POST /v1/directions.brackets                  JSON  (ETag)
  POST /v1/directions.cancelMatch               JSON  (Idempotency-Key)  (If-Match)
  POST /v1/directions.clock                     JSON  (ETag)
  POST /v1/directions.close                     JSON  (Idempotency-Key)  (If-Match)
  POST /v1/directions.confirmAllProposals       JSON  (Idempotency-Key)  (If-Match)
  POST /v1/directions.confirmProposal           JSON  (Idempotency-Key)  (If-Match)
  POST /v1/directions.correctResult             JSON  (Idempotency-Key)  (If-Match)
  POST /v1/directions.create                    JSON  (Idempotency-Key)
  POST /v1/directions.detachMatch               JSON  (Idempotency-Key)  (If-Match)
  POST /v1/directions.directory                 JSON  (ETag)
  POST /v1/directions.enterForfeit              JSON  (Idempotency-Key)  (If-Match)
  POST /v1/directions.enterParticipants         JSON  (Idempotency-Key)  (If-Match)
  POST /v1/directions.enterResult               JSON  (Idempotency-Key)  (If-Match)
  POST /v1/directions.freeParticipants          JSON  (ETag)
  POST /v1/directions.get                       JSON  (ETag)
  POST /v1/directions.history                   JSON  (ETag)
  POST /v1/directions.lastDecision              JSON  (ETag)
  POST /v1/directions.list                      JSON  (ETag)
  POST /v1/directions.makeAbsent                JSON  (Idempotency-Key)  (If-Match)
  POST /v1/directions.makeAvailable             JSON  (Idempotency-Key)  (If-Match)
  POST /v1/directions.moveMatchToTable          JSON  (Idempotency-Key)  (If-Match)
  POST /v1/directions.pageHtml                  JSON  (ETag)
  POST /v1/directions.pairingSheetHtml          JSON  (ETag)
  POST /v1/directions.participants              JSON  (ETag)
  POST /v1/directions.previewConfig             JSON
  POST /v1/directions.reinstate                 JSON  (Idempotency-Key)  (If-Match)
  POST /v1/directions.reopen                    JSON  (Idempotency-Key)  (If-Match)
  POST /v1/directions.setConfig                 JSON  (Idempotency-Key)  (If-Match)
  POST /v1/directions.setTables                 JSON  (Idempotency-Key)  (If-Match)
  POST /v1/directions.slots                     JSON  (ETag)
  POST /v1/directions.standings                 JSON  (ETag)
  POST /v1/directions.standingsCsv              JSON  (ETag)
  POST /v1/directions.startMatch                JSON  (Idempotency-Key)  (If-Match)
  POST /v1/directions.tableGrid                 JSON  (ETag)
  POST /v1/directions.updatePair                JSON  (Idempotency-Key)  (If-Match)
  POST /v1/directions.updateParticipant         JSON  (Idempotency-Key)  (If-Match)
  POST /v1/directions.withdraw                  JSON  (Idempotency-Key)  (If-Match)
duels
  POST /v1/duels.act                            custom
  POST /v1/duels.contribute                     custom
  POST /v1/duels.create                         JSON  (Idempotency-Key)
  POST /v1/duels.discard                        custom
  POST /v1/duels.flag                           custom
  POST /v1/duels.forfeit                        custom
  POST /v1/duels.get                            custom
  POST /v1/duels.list                           JSON
  POST /v1/duels.open                           custom
  POST /v1/duels.stop                           custom
  POST /v1/duels.suspend                        custom
events
  POST /v1/events.alias.list                    JSON
  POST /v1/events.alias.remove                  JSON
  POST /v1/events.alias.set                     JSON
  POST /v1/events.alias.suggest                 JSON
exports
  POST /v1/exports.json                         custom
  POST /v1/exports.plan                         JSON
  POST /v1/exports.planIds                      JSON
  POST /v1/exports.sqlite                       custom
filters
  POST /v1/filters.delete                       JSON
  POST /v1/filters.list                         NDJSON
  POST /v1/filters.loadEditPosition             JSON
  POST /v1/filters.loadExcludePosition          JSON
  POST /v1/filters.save                         JSON
  POST /v1/filters.saveEditPosition             JSON
  POST /v1/filters.saveExcludePosition          JSON
  POST /v1/filters.setPinned                    JSON
  POST /v1/filters.update                       JSON
gammonnet
  POST /v1/gammonnet.analyzeMissing             custom
  POST /v1/gammonnet.analyzeMissing.cancel      custom
  POST /v1/gammonnet.compare                    custom
  POST /v1/gammonnet.cubeMatrix                 custom
  POST /v1/gammonnet.evaluate                   custom
  POST /v1/gammonnet.sweepStale                 custom
history
  POST /v1/history.clear                        JSON
  POST /v1/history.load                         JSON
  POST /v1/history.save                         JSON
imports
  POST /v1/imports.batch                        custom
  POST /v1/imports.batch.cancel                 JSON
  POST /v1/imports.batch.status                 JSON
  POST /v1/imports.bgf                          custom
  POST /v1/imports.cancel                       custom
  POST /v1/imports.db                           custom
  POST /v1/imports.files                        JSON
  POST /v1/imports.gnubg                        custom
  POST /v1/imports.json                         custom
  POST /v1/imports.list                         JSON
  POST /v1/imports.ogxm                         custom
  POST /v1/imports.position                     custom
  POST /v1/imports.report                       JSON
  POST /v1/imports.studyQueue                   JSON
  POST /v1/imports.xg                           custom
lessons
  POST /v1/lessons.addStep                      JSON  (Idempotency-Key)
  POST /v1/lessons.create                       JSON  (Idempotency-Key)
  POST /v1/lessons.delete                       JSON
  POST /v1/lessons.doneSteps                    JSON
  POST /v1/lessons.get                          JSON
  POST /v1/lessons.html                         JSON
  POST /v1/lessons.list                         JSON
  POST /v1/lessons.removeStep                   JSON
  POST /v1/lessons.reorderSteps                 JSON
  POST /v1/lessons.setStepDone                  JSON
  POST /v1/lessons.update                       JSON
  POST /v1/lessons.updateStep                   JSON
librarySettings
  POST /v1/librarySettings.load                 JSON
  POST /v1/librarySettings.save                 JSON
maintenance
  POST /ops/maintenance.vacuum                  custom
  POST /v1/maintenance.cancel                   custom
  POST /v1/maintenance.count                    JSON
  POST /v1/maintenance.ids                      JSON
  POST /v1/maintenance.reencode                 custom
  POST /v1/maintenance.run                      custom
  POST /v1/maintenance.status                   JSON
matches
  POST /v1/matches.byPosition                   JSON
  POST /v1/matches.count                        JSON
  POST /v1/matches.createGame                   JSON
  POST /v1/matches.createMove                   JSON
  POST /v1/matches.delete                       JSON
  POST /v1/matches.duplicates                   JSON
  POST /v1/matches.exportMat                    custom
  POST /v1/matches.findByHash                   JSON
  POST /v1/matches.games                        NDJSON
  POST /v1/matches.get                          JSON
  POST /v1/matches.lastVisited                  JSON
  POST /v1/matches.list                         NDJSON
  POST /v1/matches.mergePlayers                 JSON
  POST /v1/matches.movePositions                NDJSON
  POST /v1/matches.moves                        NDJSON
  POST /v1/matches.movesByMatch                 NDJSON
  POST /v1/matches.origin                       JSON
  POST /v1/matches.repair                       custom
  POST /v1/matches.save                         JSON
  POST /v1/matches.scoreMoves                   JSON
  POST /v1/matches.setLastVisitedPosition       JSON
  POST /v1/matches.setVideoSource               JSON
  POST /v1/matches.swapPlayers                  JSON
  POST /v1/matches.update                       JSON
  POST /v1/matches.updateComment                JSON
met
  POST /v1/met.import                           JSON
  POST /v1/met.list                             JSON
  POST /v1/met.ofAnalysis                       JSON
  POST /v1/met.setCurrent                       JSON
metadata
  POST /v1/metadata.counts                      JSON
  POST /v1/metadata.countsEstimate              JSON
  POST /v1/metadata.version                     JSON
openingbook
  POST /v1/openingbook.grade                    JSON
  POST /v1/openingbook.question                 JSON
  POST /v1/openingbook.status                   JSON
pile
  POST /v1/pile.state                           JSON
  POST /v1/pile.toggle                          JSON
players
  POST /v1/players.alias.list                   JSON
  POST /v1/players.alias.remove                 JSON
  POST /v1/players.alias.set                    JSON
  POST /v1/players.alias.suggest                JSON
  POST /v1/players.main.clear                   JSON
  POST /v1/players.main.get                     JSON
  POST /v1/players.main.plan                    JSON
  POST /v1/players.main.set                     JSON
  POST /v1/players.matchIds                     JSON
positions
  POST /v1/positions.count                      JSON
  POST /v1/positions.delete                     JSON
  POST /v1/positions.epc                        JSON
  POST /v1/positions.exists                     JSON
  POST /v1/positions.explain                    JSON
  POST /v1/positions.fromImage                  custom
  POST /v1/positions.fromOGID                   JSON
  POST /v1/positions.fromXGID                   JSON
  POST /v1/positions.fromXGP                    JSON
  POST /v1/positions.indexOf                    JSON
  POST /v1/positions.legalMoves                 JSON
  POST /v1/positions.list                       NDJSON
  POST /v1/positions.listIds                    JSON
  POST /v1/positions.load                       JSON
  POST /v1/positions.loadByIds                  JSON
  POST /v1/positions.parseText                  JSON
  POST /v1/positions.reclassifyPhases           JSON
  POST /v1/positions.repairCrawford             JSON
  POST /v1/positions.save                       JSON  (Idempotency-Key)
  POST /v1/positions.setIndividuallyImported    JSON
  POST /v1/positions.similar                    JSON
  POST /v1/positions.update                     JSON
quiz
  POST /v1/quiz.gradeChecker                    JSON
  POST /v1/quiz.gradeCheckerMove                JSON
  POST /v1/quiz.gradeCube                       JSON
rencontres
  POST /v1/rencontres.attach                    JSON  (Idempotency-Key)  (If-Match)
  POST /v1/rencontres.create                    JSON  (Idempotency-Key)
  POST /v1/rencontres.detach                    JSON  (Idempotency-Key)  (If-Match)
  POST /v1/rencontres.get                       JSON  (ETag)
  POST /v1/rencontres.list                      JSON  (ETag)
  POST /v1/rencontres.pageHtml                  JSON  (ETag)
  POST /v1/rencontres.ranking                   JSON
  POST /v1/rencontres.setBreaks                 JSON  (Idempotency-Key)  (If-Match)
  POST /v1/rencontres.setEventRooms             JSON  (Idempotency-Key)  (If-Match)
  POST /v1/rencontres.setTableOutOfService      JSON  (Idempotency-Key)  (If-Match)
  POST /v1/rencontres.setTables                 JSON  (Idempotency-Key)  (If-Match)
  POST /v1/rencontres.trash                     JSON  (Idempotency-Key)  (If-Match)
  POST /v1/rencontres.update                    JSON  (Idempotency-Key)  (If-Match)
rollout
  POST /v1/rollout.filter                       custom
  POST /v1/rollout.filter.cancel                custom
  POST /v1/rollout.list                         JSON
  POST /v1/rollout.position                     custom
search
  POST /v1/search.count                         JSON
  POST /v1/search.find                          NDJSON
  POST /v1/search.ids                           JSON
  POST /v1/search.indexOf                       JSON
  POST /v1/search.parse                         JSON
  POST /v1/search.query                         custom
searchHistory
  POST /v1/searchHistory.deleteEntry            JSON
  POST /v1/searchHistory.list                   NDJSON
  POST /v1/searchHistory.save                   JSON
session
  POST /v1/session.clear                        JSON
  POST /v1/session.load                         JSON
  POST /v1/session.save                         JSON
stats
  POST /v1/stats.analysisEngines                JSON
  POST /v1/stats.biases                         JSON
  POST /v1/stats.breakdownPositionCounts        JSON
  POST /v1/stats.compute                        JSON
  POST /v1/stats.dateRange                      JSON
  POST /v1/stats.headToHead                     JSON
  POST /v1/stats.matchBadges                    JSON
  POST /v1/stats.matchDecisionLosses            JSON
  POST /v1/stats.matchDetail                    JSON
  POST /v1/stats.matchIds                       JSON
  POST /v1/stats.matchMoveGrades                JSON
  POST /v1/stats.matchReview                    JSON
  POST /v1/stats.matchTimeSummary               JSON
  POST /v1/stats.playerContrast                 JSON
  POST /v1/stats.playerNames                    JSON
  POST /v1/stats.playerTable                    JSON
  POST /v1/stats.positionIdsByMatch             JSON
  POST /v1/stats.positionIdsBySelection         JSON
  POST /v1/stats.positionIdsByTournament        JSON
  POST /v1/stats.prByWindow                     JSON
  POST /v1/stats.ranking                        JSON
  POST /v1/stats.rebuildMatchStats              JSON
  POST /v1/stats.recurringErrors                JSON
  POST /v1/stats.report                         JSON
  POST /v1/stats.studyEffect                    JSON
  POST /v1/stats.studyIds                       JSON
  POST /v1/stats.studyPlan                      JSON
  POST /v1/stats.studyPlanIds                   JSON
  POST /v1/stats.studyPlanQueue                 JSON
  POST /v1/stats.timeErrors                     JSON
  POST /v1/stats.tournamentBadges               JSON
  POST /v1/stats.tournamentIds                  JSON
  POST /v1/stats.tournamentReview               JSON
  POST /v1/stats.training                       JSON
study
  POST /v1/study.backlog                        JSON
  POST /v1/study.setStudied                     JSON
tenant
  POST /ops/tenant.purge                        custom
tenants
  POST /v1/tenants.quota                        JSON
tournaments
  POST /v1/tournaments.addMatch                 JSON
  POST /v1/tournaments.create                   JSON  (Idempotency-Key)
  POST /v1/tournaments.delete                   JSON
  POST /v1/tournaments.get                      JSON
  POST /v1/tournaments.list                     NDJSON
  POST /v1/tournaments.matches                  NDJSON
  POST /v1/tournaments.removeMatch              JSON
  POST /v1/tournaments.reorderMatches           JSON
  POST /v1/tournaments.setMatchByName           JSON
  POST /v1/tournaments.tournamentOf             JSON
  POST /v1/tournaments.update                   JSON
  POST /v1/tournaments.updateComment            JSON
training
  POST /v1/training.missed                      JSON
  POST /v1/training.numberStats                 JSON
  POST /v1/training.save                        JSON  (Idempotency-Key)
  POST /v1/training.sessions                    JSON
transcriptions
  POST /v1/transcriptions.abandon               JSON  (Idempotency-Key)  (If-Match)
  POST /v1/transcriptions.apply                 JSON  (Idempotency-Key)  (If-Match)
  POST /v1/transcriptions.close                 JSON
  POST /v1/transcriptions.create                JSON
  POST /v1/transcriptions.editMatch             JSON
  POST /v1/transcriptions.exportMat             JSON
  POST /v1/transcriptions.finish                JSON  (Idempotency-Key)  (If-Match)
  POST /v1/transcriptions.get                   custom
  POST /v1/transcriptions.list                  JSON
  POST /v1/transcriptions.losses                JSON
  POST /v1/transcriptions.materialize           JSON  (Idempotency-Key)
  POST /v1/transcriptions.open                  JSON
  POST /v1/transcriptions.redo                  JSON  (Idempotency-Key)  (If-Match)
  POST /v1/transcriptions.undo                  JSON  (Idempotency-Key)  (If-Match)
trash
  POST /v1/trash.count                          JSON
  POST /v1/trash.deleteCollection               JSON
  POST /v1/trash.deleteComment                  JSON
  POST /v1/trash.deleteMatch                    JSON
  POST /v1/trash.deletePosition                 JSON
  POST /v1/trash.discard                        JSON
  POST /v1/trash.empty                          JSON
  POST /v1/trash.list                           JSON
  POST /v1/trash.restore                        JSON
events
  GET  /v1/events                               SSE

Idempotency

Most methods need no special mechanism: reads have no side effects, and the writes of positions.* are idempotent in effect thanks to the Zobrist hash of the content — saving the same position twice returns the same row, never a duplicate. 49 methods accept an optional Idempotency-Key header: those whose two calls are two distinct effects, and positions.save, whose response says whether the call created the position (created) and would say so wrongly if replayed after a lost response. A call replayed with the same key returns the result of the first attempt instead of repeating its effect — see the “(Idempotency-Key)” mark in the table above. No other method needs or accepts this header.

Conditional reads

Methods marked “(ETag)” return an ETag header. Sending it back in If-None-Match gets a body-less 304 response as long as nothing the method reads has changed — see Tournament direction and events.

Timecodes of a transcription

A transcriptions.apply gesture can carry the video instant at which it is made, in milliseconds from the start of the media: TickMS, read only when HasTick is true (0 is an instant). enter_die makes it the timecode of the roll (the first die key counts); enter_play, validate, dance, double, take, pass and resign make it the timecode of the action, on a new action only: an in-place correction keeps the timecodes it had. The set_timecode gesture sets TickMS (with HasTick) and RollTickMS (with HasRollTick) on the cursor’s action; a negative value clears the timecode. The set_video gesture attaches the video source named by VideoSource (http(s) URL or local path), and an empty string detaches it; set_header also sets it when its header names one, but never clears it.

The seek_cursor gesture puts the cursor on the action of rank At, the end of the document past the last one, without writing anything or stacking on the undo stack: this is how the cursor follows a playing video. A decision_ms accompanied by decision_estimated is an estimate: a play without an action timecode, measured from the roll to the next action’s first instant.

The rendered state carries the source in header.video_source, the timecodes of each action in roll_tick_ms and tick_ms, and, on each annotated action, the durations decision_ms and cube_decision_ms: measured by the Arbiter when they are, otherwise deduced from the timecodes. A timecode earlier than the previous one is flagged by the timecode_backwards inconsistency and leaves the durations that depend on it unknown.