エンドポイント一覧
この文書は、公開ドキュメントとして扱う API を対象に、現行実装のレスポンス形状・要件を記載します。
対象外(内部向け)
以下は内部運用/デバッグ用途のため、この文書の詳細対象外です。
GET /api/debug/enablePOST /api/finalize/callback
公開対象 API 一覧
| メソッド | パス | 主用途 | X-Session-ID |
|---|---|---|---|
POST | /api/session | セッション作成 | 不要 |
POST | /api/vote | 投票送信 | 必須 |
GET | /api/progress | ボット投票進捗 | 必須 |
POST | /api/finalize | 集計/証明生成 | 必須 |
POST | /api/finalize/cancel | 非同期集計キャンセル | 必須 |
GET | /api/sessions/:sessionId/status | 非同期集計ステータス | 不要 |
GET | /api/verify | 検証ペイロード取得 | 必須 |
POST | /api/verification/run | STARK 検証実行 | 必須 |
GET | /api/verification/bundles/:sessionId/:executionId | バンドル ZIP 取得 | 不要 |
GET | /api/verification/bundles/:sessionId/:executionId/report | 検証レポート取得 | 不要 |
GET | /api/bulletin | 掲示板一覧 | 必須 |
GET | /api/bulletin/:voteId | 投票エントリ + 証明 | 必須 |
GET | /api/bulletin/:voteId/proof | 最小包含証明 | 必須 |
GET | /api/bulletin/consistency-proof | 整合性証明 | 必須 |
GET | /api/botdata/:id | ボット投票データ | 必須 |
GET | /api/bitmap-proof | ビットマップ証明材料 | 実装依存 |
GET | /api/sth | STH スナップショット | 必須 |
GET | /api/zkvm-input-hash | zkVM 入力コミットメント | 不要 |
共通の実装上の注意
POST /api/voteとPOST /api/finalizeは Turnstile 検証を実行します。POST /api/verification/runは Turnstile なしで、/api/finalizeと同じ zkVM レート制限を使用します。- エラー形式はエンドポイントにより異なります(標準化 payload と独自 payload が混在)。
基本フロー API
POST /api/session
新規セッションを作成します。
レスポンス(200):
data.sessionIddata.electionIddata.electionConfigHashdata.logId
備考:
- このハンドラでは
X-Session-IDは不要です。
POST /api/vote
ユーザー投票を保存し、ボット投票を非同期開始します。
要件:
- ヘッダー:
X-Session-ID必須 - ボディ:
commitment,vote,rand(turnstileTokenは開発設定により省略可) - Turnstile 検証あり
- 投票用レート制限あり
レスポンス(200):
data.voteIddata.commitmentdata.bulletinIndexdata.bulletinRootAtCastdata.timestamp
主なエラー:
SESSION_ID_REQUIRED(400)SESSION_NOT_FOUND(404)CAPTCHA_FAILED(403)GLOBAL_LIMIT_EXCEEDED(503)ALREADY_VOTED(400)SESSION_FINALIZED(400)INVALID_VOTE_CHOICE(400)INVALID_COMMITMENT(400)DUPLICATE_VOTE(409)
GET /api/progress
投票進捗を取得します。
要件:
- ヘッダー:
X-Session-ID必須
レスポンス(200):
data.countdata.totaldata.completeddata.userVoteddata.finalized
主なエラー:
SESSION_ID_REQUIRED(400)SESSION_NOT_FOUND(404)
POST /api/finalize
集計と証明生成を開始します。同期/非同期の 2 形態があります。
要件:
- ヘッダー:
X-Session-ID必須 - ボディ:
scenarioId(S0-S5),turnstileToken(環境により必須) - Turnstile 検証あり
- zkVM レート制限あり
レスポンス(200, 同期):
data.sessionIddata.tallydata.bulletinRootdata.verifiedTallydata.voteReceiptdata.receipt(同期成功レスポンスで返却)data.receiptPublication(保存時)data.imageIddata.userVotedata.missingIndicesdata.invalidIndicesdata.countedIndicesdata.totalExpecteddata.treeSizedata.sthDigestdata.includedBitmapRootdata.inputCommitmentdata.verificationStatusdata.verificationBundleUrl/data.verificationReportUrl/data.verificationReport(条件付き)data.verificationExecutionId(条件付き)data.s3BundleUrl/data.s3BundleKey/data.s3UploadedAt/data.s3BundleExpiresAt(条件付き)data.tamperSummary(条件付き)
レスポンス(202, 非同期):
executionIdstatusUrlstatequeue(nullの場合あり)
主なエラー:
SESSION_ID_REQUIRED(400)SESSION_NOT_FOUND(404)CAPTCHA_FAILED(403)INVALID_REQUEST(400)VERIFICATION_FAILED(400, CT proof unavailable)USER_NOT_VOTED(400)VOTING_NOT_COMPLETE(400)SESSION_ALREADY_FINALIZED(400)ZKVM_RATE_LIMIT_EXCEEDED(429)GLOBAL_LIMIT_EXCEEDED(503)Invalid ImageID(400, 独自形式{ error: "Invalid ImageID", details: { expected, actual } })
POST /api/finalize/cancel
進行中の非同期集計をキャンセルします。
要件:
FINALIZE_ASYNC_MODE=trueのときのみ有効- ヘッダー:
X-Session-ID(x-session-idも受理) - ボディ:
executionId必須、reason任意
レスポンス(200):
state
主なエラー(このエンドポイントは独自形式):
404: Async finalization disabled / Session not found400: ヘッダー欠落、JSON 不正、payload 不正409: 現在状態ではキャンセル不可500: Session store unavailable501: ストアが cancellation 非対応
GET /api/sessions/:sessionId/status
非同期集計の状態を返します。
要件:
- パスパラメータ
sessionId必須
レスポンス(200):
sessionIdfinalizationState(nullの場合あり)queue(nullの場合あり)progress(条件付き)finalizationResult(nullの場合あり)stepFunctions(条件付き)asyncFinalizationMode(enabled/disabled)
主なエラー(独自形式):
400: Session ID is required404: Session not found
検証 API
GET /api/verify
検証画面向けの統合ペイロードを返します。
要件:
- ヘッダー:
X-Session-ID必須 - クエリ:
refreshS3=1,includeJournal=1(任意)
レスポンス(200):
data.electionIddata.electionConfigHashdata.logIddata.tallydata.bulletinRootdata.scenarioIddata.verificationStatusdata.verificationBundleUrl/data.verificationReportUrl/data.verificationReport(条件付き)data.verificationSteps/data.verificationChecksdata.s3BundleUrl/data.s3BundleKey/data.s3UploadedAt/data.s3BundleExpiresAt(条件付き)data.imageIddata.tamperDetecteddata.verifiedTallydata.missingIndicesdata.invalidIndicesdata.countedIndicesdata.totalExpecteddata.treeSizedata.excludedCountdata.sthDigestdata.includedBitmapRootdata.inputCommitmentdata.seenIndicesCount(条件付き)data.journalStatusdata.journal(includeJournal=1のとき)data.voteReceipt(条件付き)data.userVote(条件付き)data.botVotesSummary(条件付き)data.verificationExecutionId(条件付き)data.tamperSummary(条件付き)
特殊レスポンス:
verificationStatusが許容セット外の場合、400 VERIFICATION_FAILEDを返しつつ、data.verificationSteps/data.verificationChecksを返します。
主なエラー:
SESSION_ID_REQUIRED(400)SESSION_NOT_FOUND(404)SESSION_NOT_FINALIZED(400)USER_NOT_VOTED(400)
POST /api/verification/run
サーバー側で STARK レシート検証を実行します。
要件:
- ヘッダー:
X-Session-ID必須 - ボディ: JSON オブジェクト(通常は空オブジェクト
{}) - zkVM レート制限あり
レスポンス(200):
data.verificationStatus(success/failed/dev_mode/not_run/running)data.verificationExecutionIddata.estimatedDurationMsdata.idempotent
挙動:
- 既存結果がある場合や実行中の場合は、再実行せず
idempotent: trueを返します。
バンドル取得 API
GET /api/verification/bundles/:sessionId/:executionId
証明バンドル bundle.zip を返します。
レスポンス:
200: ZIP バイナリ302: S3 presigned URL へリダイレクト400: パラメータ不正404: バンドル未検出500: ダウンロード URL 生成失敗 / 読み込み失敗
GET /api/verification/bundles/:sessionId/:executionId/report
検証レポート verification.json を返します。
レスポンス:
200: JSON302: S3 presigned URL へリダイレクト400: パラメータ不正404: レポート未検出500: ダウンロード URL 生成失敗 / 読み込み失敗
掲示板 API
GET /api/bulletin
掲示板一覧を返します。
要件:
- ヘッダー:
X-Session-ID必須 - クエリ:
offset,limit(任意)
レスポンス(200):
commitmentsbulletinRoottreeSizetimestamprootHistory(条件付き)nextOffset/hasMore(ページング時)
主なエラー:
SESSION_ID_REQUIRED(400)SESSION_NOT_FOUND(404)INVALID_OFFSET(400)INVALID_LIMIT(400)
GET /api/bulletin/:voteId
投票単位の包含証明を返します。
要件:
- ヘッダー:
X-Session-ID必須 - パス:
voteId(UUID v4 形式)
レスポンス(200):
voteIdcommitmentbulletinIndexmerklePathbulletinRootAtCasttreeSizeproofMode(rfc6962)
主なエラー:
INVALID_VOTE_ID(400)VOTE_NOT_FOUND(404)VERIFICATION_FAILED(400, CT proof unavailable)
GET /api/bulletin/:voteId/proof
最小形式の包含証明を返します。
要件:
- ヘッダー:
X-Session-ID必須 - セッションは finalized 必須
- パス:
voteId
アクセス制御:
- 原則は「そのセッションのユーザー投票」のみ
- 例外としてシナリオ
S3/S4では対象ボット票を許可
レスポンス(200):
voteIdproof.leafIndexproof.merklePathproof.treeSizeproof.bulletinRootAtCastproof.proofMode
キャッシュ:
ETag対応If-None-Match一致時は304
GET /api/bulletin/consistency-proof
RFC6962 整合性証明を返します。
要件:
- ヘッダー:
X-Session-ID必須 - クエリ:
oldSize,newSize必須
レスポンス(200):
oldSizenewSizerootAtOldSizerootAtNewSizeproofNodesoldSubtreeHashes/appendSubtreeHashes(条件付き)timestamp
備考:
- このエンドポイントは独自のエラー JSON を返します。
GET /api/botdata/:id
ボット投票(1..63)のデータと証明を返します。
要件:
- ヘッダー:
X-Session-ID必須 - セッション finalized 必須
レスポンス(200):
data.iddata.votedata.randomdata.commitmentdata.voteIddata.timestampdata.proof(leafIndex,merklePath,treeSize,bulletinRootAtCast,proofMode)
主なエラー:
INVALID_BOT_ID(400)SESSION_NOT_FINALIZED(400)BOT_DATA_NOT_FOUND(404)
補助 API
GET /api/bitmap-proof
ビットマップ包含証明の材料を返します。
要件:
- クエリ:
i(0 以上整数)必須 X-Session-IDはストア実装依存(Mock/File は省略可、Amplify は実質必須)- 互換性のため
X-Session-IDの指定を推奨
レスポンス(200):
leafChunkauditPath
キャッシュ:
ETag対応If-None-Match一致時304Cache-Control: private ... immutable
エラー(独自コード):
INVALID_INDEX(400)BITMAP_NOT_FOUND(404)INTERNAL_ERROR(500)
GET /api/sth
STH スナップショットを返します。
要件:
- ヘッダー:
X-Session-ID必須 - finalized セッションのみ
レスポンス(200):
sth.sthDigeststh.bulletinRootsth.treeSizesth.timestampsth.logId
備考:
- 現行実装の
sth.timestampはジャーナル内時刻ではなく、session.lastActivityを返します。
主なエラー:
SESSION_ID_REQUIRED(400)SESSION_NOT_FOUND(404)SESSION_NOT_FINALIZED(404, このエンドポイント固有の扱い)
GET /api/zkvm-input-hash
セッション由来の zkVM 入力コミットメントを返します。
要件:
- クエリ:
sessionId必須 - クエリ:
includeData任意(true/1/yesで有効)
レスポンス(200):
inputCommitmentdata(includeData有効時のみ)
主なエラー(独自形式):
INVALID_REQUEST(400)SESSION_NOT_FOUND(404)SESSION_NOT_FINALIZED(400)CT_PROOF_UNAVAILABLE(400)INTERNAL_ERROR(500)