API コントラクト

この付録はソースコードから生成されます(go run ./cmd/openapi-gen。完全な契約とスキーマについてはリポジトリのルートにある openapi.yaml を参照してください)。直接編集しないでください。次回の生成で変更が上書きされます。各ファミリーは、デーモンが公開する POST /v1/<ファミリー>.<メソッド>メソッドをまとめたもので(ヘッドレスモード(サーバー) 参照)、レスポンスの形式(JSON、またはストリーミングリストの場合は NDJSON)と、存在する場合は任意の Idempotency-Key ヘッダーへの言及を含みます。

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

冪等性

ほとんどのメソッドには特別な仕組みは不要です。読み取りに副作用はなく、positions.* の書き込みは内容の Zobrist ハッシュのおかげで効果が冪等です。同じポジションを 2 回保存しても同じ行が返り、重複は生じません。49 個のメソッドは任意の Idempotency-Key ヘッダーを受け付けます。これは、2 回の呼び出しが 2 つの別個の効果になるメソッドと、応答が呼び出しによってポジションが作成されたか(created)を示すため、応答が失われた後に再送されると誤った内容を返してしまう positions.save です。同じキーで再送された呼び出しは、効果を繰り返さず最初の試行の結果を返します。上の表の「(Idempotency-Key)」の印を参照してください。それ以外のメソッドはこのヘッダーを必要とせず、受け付けません。

条件付き読み取り

「(ETag)」と記されたメソッドは ETag ヘッダーを返します。これを If-None-Match に付けて送り返すと、メソッドが読み取る内容に変化がない限り、本文のない 304 応答が返ります — 大会の運営とイベント を参照してください。

文字起こしのタイムコード

transcriptions.apply のジェスチャーは、それが行われた動画上の時刻を、メディアの先頭からのミリ秒で持てます。これが TickMS で、HasTick が true のときだけ読まれます(0 も時刻です)。enter_die はこれをロールのタイムコードにし(最初のダイスキーが有効)、enter_play、validate、dance、double、take、pass、resign はこれをアクションのタイムコードにします。ただし新しいアクションに限り、その場での修正は元のタイムコードを保ちます。set_timecode ジェスチャーは、カーソル位置のアクションに TickMS (HasTick とともに)と RollTickMS (HasRollTick とともに)を設定し、負の値はタイムコードを消去します。set_video ジェスチャーは VideoSource で指定された動画ソース(http(s) の URL またはローカルパス)を関連付け、空文字列はそれを解除します。set_header も、ヘッダーが動画ソースを指定している場合はそれを設定しますが、消去することはありません。

seek_cursor ジェスチャーは、カーソルを順位 At のアクション(最後を越えれば文書の末尾)に置きます。何も書き込まず、元に戻すスタックにも積みません。カーソルが再生中の動画を追うのはこの仕組みによります。decision_estimated を伴う decision_ms は推定値です。アクションのタイムコードがない手について、ロールから次のアクションの最初の時刻までを測ったものです。

レンダリングされた状態は、ソースを header.video_source に、各アクションのタイムコードを roll_tick_ms と tick_ms に持ち、注釈付きの各アクションには所要時間 decision_ms と cube_decision_ms を持ちます。これらは測定されている場合は審判(Arbiter)が測定した値で、そうでなければタイムコードから導かれます。直前より前のタイムコードは timecode_backwards の不整合として示され、それに依存する所要時間は不明のままになります。