Контракт 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.* идемпотентны по своему действию благодаря хешу Зобриста содержимого — повторное сохранение той же позиции возвращает ту же строку, а не дубликат. 49 методов принимают необязательный заголовок Idempotency-Key: те, у которых два вызова — это два разных действия, и positions.save, ответ которого сообщает, создал ли вызов позицию (created), и сообщил бы это неверно при повторе после потерянного ответа. Вызов, повторённый с тем же ключом, возвращает результат первой попытки вместо повторения её действия — см. пометку «(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 (URL http(s) или локальный путь), пустая строка отвязывает его; set_header тоже задаёт его, когда его заголовок называет источник, но никогда не стирает.

Жест seek_cursor ставит курсор на действие с номером At, а за последним — в конец документа, ничего не записывая и не попадая в стек отмены: так курсор следует за воспроизводимым видео. decision_ms вместе с decision_estimated — это оценка: ход без метки действия, измеренный от броска до первого момента следующего действия.

Отрисованное состояние несёт источник в header.video_source, таймкоды каждого действия в roll_tick_ms и tick_ms и, у каждого аннотированного действия, длительности decision_ms и cube_decision_ms: измеренные Арбитром (Arbiter), когда они измерены, иначе выводимые из таймкодов. Таймкод, предшествующий предыдущему, помечается несогласованностью timecode_backwards и оставляет неизвестными зависящие от него длительности.