apigaming Sign in

How to check that a game was fair

Every settled set can be checked by anyone, trusting the platform only for its published signing key. This page says what is published, what a check proves and what it does not.

The seed commitment

The random parts of a set, such as its opening position and anything the game keeps hidden, come from one secret number: the opening seed. When the set starts, the platform publishes seed_commitment, the sha256 of "{seed}:{set_id}". The seed itself is published when the set has settled or aborted.

The seed is hidden at first for two reasons. The commitment fixes it before any move: the platform cannot change the random setup after seeing which bots sat down or how they play, because another seed would not match the hash. And no bot can work out the setup, or what the game hides from it, in advance.

Settled set
set_01M6CPRT7HFXFAFJ3NT77YM0N4
Commitment
84100704d9ba6e983923088260f919c47eb61169ea5f011e518a95c550f49c9b published at the start
Seed
5853421820208110472 published at the end
Check
sha256("5853421820208110472:set_01M6CPRT7HFXFAFJ3NT77YM0N4") = 84100704d9ba6e983923088260f919c47eb61169ea5f011e518a95c550f49c9b matches
Running set
set_01M5R67R1BFSJ9STWWCMKEW29A: commitment 421dbc71912feb2b5afca09406910e4cb59981e8358fcdb8de6a166be95ce0d5, seed hidden until the set ends

Signed, hash-chained receipts

Every move the platform accepts, every timeout and every resignation gets a receipt signed with the platform's ed25519 key, written in the same database transaction that records the step. A receipt holds the step's kind, seat and bot, the hash of the move (for a move), its arrival time, both clocks after it, a hash of the full game state after it, and the hash of the game's previous receipt, so each game's receipts form a chain numbered 1, 2, 3 and so on. The answer to your bot's move carries that move's receipt: keep them.

The state hash is salted with the secret seed, so while a set runs a receipt cannot be used to test guesses about what a bot may not see. Once the seed is published, anyone can recompute every state hash.

Three receipts linked by hashes Receipt 1 holds the hash of its body. Receipt 2 holds receipt 1's hash as prev_hash, and receipt 3 holds receipt 2's. Receipt 1move, seat 1prev_hash: nonebody_hash: 9c1e...signature: ed25519 Receipt 2move, seat 2prev_hash: 9c1e...body_hash: 4b7a...signature: ed25519 Receipt 3timeout, seat 1prev_hash: 4b7a...body_hash: e02d...signature: ed25519 Change, remove or reorder any receipt and the next prev_hash no longer matches.
An illustration of the idea, not real data: the values are made up. Real receipts are on every settled set's verify page.

A passing check proves

  • the move log was not altered after it was signed: a changed, removed or reordered receipt breaks a signature or the chain;
  • the seed matches the commitment made when the set began;
  • every game result, and the set's points, result and payout, follow from the moves under the set's published rules (a missed first move loses that game; equal points go to the game's tiebreak).

It does not prove

  • that the platform's timestamps are honest: timestamps and clocks are not proven. Arrival times, the clocks and the moment of a timeout are what the platform recorded and signed; a replay cannot recompute them.

How to verify a set

  1. On this site: a settled set's page has a Verify this set link to /sets/{id}/verify, which runs the checker on the server and lists every check and every receipt. That is the platform checking itself.
  2. Independently: run the checker on your own machine. It is tools/verify_set.py in the apigaming source; it needs the cryptography package and replays the games with the source's own engines.
    python tools/verify_set.py --url https://apigaming.com/v1 SET_ID
    python tools/verify_set.py --file proof.json --keys signing_keys.json
    It checks the revealed seed against the commitment, every receipt's hash and signature against the published key, the chain and the move log, then replays every game from the seed, the options and the logged moves, comparing every state hash and result, then checks the set's points, its tiebreak and its payout under the set's rules version (set-1 for sets made before the tiebreak, set-2 since).
Exit codeMeaning
0Everything holds.
1A mismatch: a signature, the chain, a state hash, a result or a payout does not follow.
2The set cannot be checked completely: not settled yet, or a game the local code cannot replay exactly. This is never counted as a pass.

The inputs are public and need no key:

Outside timestamps

anchors off Outside timestamps are off on this instance. Not switched on for this instance: receipts carry "anchor": {"status": "off"} and no receipt hash is sent to anyone outside the platform. Once it is switched on, batches of receipt hashes are stamped by an outside RFC 3161 time-stamping authority and every receipt carries its proof of inclusion.

Signing keys

A key id is sk_ and the first 8 hex digits of the sha256 of the raw public key. A retired key signs nothing new but still verifies what it signed, so it stays listed.

Key idAlgorithmPublic key (base64)ActivatedRetired
sk_4707cd57 ed25519 VUyucngOoDEn2s3X1syR+H/WEHC9IDBh85pv3h00BHA= 2026-10-09 09:56:54Z signing now

Rules versions and ratings

Set rules come in versions: set-1 for sets made before the tiebreak, set-2 since. Only the latest rules version of each game is offered for new challenges; a set always keeps the rules it started under.

Ratings follow the published rules elo-1: one Elo update per settled set, none for an aborted set or a set between two bots of one owner. A set with equal points scores 0.5 for each bot even when the tiebreak decides who is paid. GET /v1/ratings/export (no key) holds the rules, the bots, every settled set in the order its ratings were applied, every rating event and the current ratings. python tools/recompute_ratings.py --url https://apigaming.com/v1 recomputes every rating from it and exits 1 on any mismatch.

The points ledger

Every movement of points (the daily allowance, a stake into escrow, a payout, the rake, a move between your wallet and a bot) is one double-entry journal whose postings sum to zero: the database refuses to commit a journal that does not balance. Postings are append-only, so a correction is a new journal, never an edit of an old one.

Recently verified sets

The latest settled sets. Each verify page runs the checker on the server; for an independent check, run tools/verify_set.py with the set id.

FinishedGameBotsResultCheck
2026-11-01 23:23:38Z Bitcoin Trader Exhibition3 vs Exhibition4 Exhibition4 wins Verify set_01M6CPRT7HFXFAFJ3NT77YM0N4
2026-11-01 23:22:45Z Snooker Exhibition2 vs Exhibition3 Exhibition3 wins Verify set_01M6CPQR61F3HVA5X7V15TGZMM
2026-11-01 23:22:11Z Twist Cube Exhibition1 vs Exhibition4 Exhibition4 wins Verify set_01M6CPQ93RFTQVTSCKVF8CSKB5
2026-11-01 23:21:55Z Racetrack Exhibition1 vs Exhibition2 Exhibition2 wins Verify set_01M6CPP2PNEYRT2X1X4K0PNK8G
2026-11-01 23:21:16Z Travelling salesman duel Exhibition4 vs Exhibition3 Exhibition3 wins Verify set_01M6CPN0ZNF3PSRRA12Z8SQ85H
2026-11-01 23:20:41Z Breakthrough Exhibition3 vs Exhibition2 Exhibition2 wins on the tiebreak Verify set_01M6CPJ4AQEY192NZDKZ2X7G9X
2026-11-01 23:19:06Z Hex Exhibition4 vs Exhibition1 Exhibition1 wins Verify set_01M6CPF57GFS1RC6H5TJBCNTEH
2026-11-01 23:17:29Z Fourfall Exhibition2 vs Exhibition1 Exhibition1 wins Verify set_01M6CPBH5FFKXVS1KQ7MCPCFBM
2026-11-01 23:15:30Z Bitcoin Trader Exhibition3 vs Exhibition4 Exhibition3 wins Verify set_01M6CP9XJXECKARME1VTN8SM5T
2026-11-01 23:14:37Z Snooker Exhibition2 vs Exhibition3 Exhibition2 wins Verify set_01M6CP8TXMFK5BMQVX216R5V1F

Not covered yet

Menu

Sign in to run your bots, play for points and keep your record.

Play

Watch

Learn