> ## Documentation Index
> Fetch the complete documentation index at: https://docs.chance.money/llms.txt
> Use this file to discover all available pages before exploring further.

# Results & proofs

> Socket-first result delivery with a GraphQL poll fallback — and what proof:null means.

After you place, the API tracks the bet on-chain, computes the outcome from the epoch seed, attempts a Groth16 entropy proof, and pushes everything to subscribers. **Socket first, poll as fallback.**

## Realtime (preferred)

```ts TypeScript theme={"theme":"css-variables"}
import { io } from 'socket.io-client'

const socket = io('https://api.chance.money', { path: '/socket.io' })

socket.on('connect', () => {
  // Rooms don't survive reconnects — always re-subscribe on connect
  socket.emit('bets:subscribe', { wallets: [playerAddress] })
})

socket.on('bets:update', (update) => {
  handleBetUpdate(update)
})
```

Subscriptions are per-wallet and unauthenticated (results and proofs are public data; the server seed is never sent). Exact event contracts: [Socket.IO — bets](/api-reference/socket-bets).

## Poll fallback

If you can't hold a socket open, poll `betResult` (single) or `betResults` (batch, max 25 ids) — same payload shape. See [GraphQL — betResult](/api-reference/bet-result).

## The update payload

Key fields of a `bets:update` (integers are decimal strings):

| Field                                           | Meaning                                                                     |
| ----------------------------------------------- | --------------------------------------------------------------------------- |
| `t`                                             | Update kind: `bet_placed`, `bet_result`, `bet_settled`, `bet_claimed`       |
| `status`                                        | `pending` → `computed` → `settled` → `claimed`                              |
| `betId`, `player`, `mode`, `commitId`           | Bet identity (`mode`: 0 Strike, 1 Range, 2 Ladder)                          |
| `stake`, `liability`, `payout`, `won`           | Outcome numbers (USDG units)                                                |
| `entropy`                                       | Hex entropy — the public PF output, an input to `claimWithProof`            |
| `proof`                                         | Hex Groth16 proof bytes for `claimWithProof` / `settleWithProof`, or `null` |
| `commitment`, `clientSeed`                      | Public proof inputs for client-side verification                            |
| `placeTxHash`, `settleTxHash`, `claimTxHash`    | Chain anchors per lifecycle step                                            |
| `houseWinAmount`, `forcedTimeout`, `claimAsset` | Settle detail (`claimAsset`: `usdg` or `chance`)                            |
| `platform`, `game`, `placedAt`, `error`         | Attribution and metadata                                                    |

## Handling `proof: null`

The API always *attempts* a proof, but delivers the result either way. When `proof` is `null`:

* Treat the result as **optimistic display only** — you cannot `claimWithProof` yet.
* Wait for the epoch to close and the seed to reveal, then use plain `claim` (it settles from the revealed seed and claims in one transaction), or keep polling `betResult`.

<Warning>
  Never treat an API result as a paid outcome. The paid truth is the on-chain settle — show optimistic UI if you like, but gate balance changes on `settled` / `claimed`. Treat `settled` and `claimed` as terminal: ignore any later `pending` / `computed` update for the same `betId` (delivery order isn't guaranteed).
</Warning>

## Onward

* [Claiming](/integrate/claiming) — turning a won result into a payout
* [Provably fair](/protocol/provably-fair) — verifying `entropy` against the commitment yourself
