Field schemas
Field-level request and response schemas for every core object.
Field-level schemas for the core objects. All monetary and probability values are decimal strings to avoid float drift. Times are RFC-3339 strings; ids are strings. price is a probability in (0,1).
Decimal strings are one convention, but the precision behind them is not. Observed on live responses:
- Money2 dp
available · balance · payout"29560.75"stake is NOT in this group — see below. Currency minor units. Safe to render as-is; never widen it, and never narrow anything else to match.
- Stakeup to 8 dp
stake"49.96617186"What the platform computed, not what moved. The wallet command rounds to the currency's minor unit before it is sent, so the debit differs from this figure — measured on 80 sandbox buys, 40 of them differ, by up to 0.0038. Reconcile a wallet ledger against the rounded amount, not against stake. On a sell the two agree, because cash-out proceeds are floored to two places at the source.
- Shares6 dp
qty · shares · position_qty"12.035215"Rounding these to money precision throws away real value — a stake buys a fractional share count, not a round one.
- Prices8 dp
price · avg_price · cashout_price"0.59609002"Probabilities in (0,1). Display them rounded; keep the original for anything you reconcile.
- Derived figuresup to 16 dp
cost · odds · realized_pnl"9.9999998921115" · "1.2035367129847771"Computed, not stored, so they carry the full working precision. Round for display only.
- Lobby prices1–4 dp
price_yes · price_base_yes · price_base_no · price_buy_yes · price_buy_no"0.66" · "0.684"Trailing zeros are stripped, so the width varies with the value. This is why these must never be compared as strings — parse to a decimal type first.
Enums
side— 1 = YES, 2 = NOorder_status— 2 = debited (stake taken, fill pending), 3 = filled, 4 = rejected. An integer, not a string. How a refused placement comes back depends on the wallet mode. On the hosted wallet an empty balance is an error envelope with its own status,409 insufficient_balance. On a self-hosted wallet it is not an HTTP error: your hook’s clean 402 voids the reservation and the response is HTTP 200 withorder_status: 4and qty and stake of “0” — a soft reject. Branch onorder_statusrather than the status line and both paths read the same. Status 4 does not promise that no money moved: an order that was debited and then voided also settles on 4, with the stake taken and refunded. Reconciliation that reads 4 as “expect no ledger entries” will flag that debit/refund pair as unexplained — pair entries byidem_key, not by the terminal status.
QuoteView
Returned by POST /b2b/v1/markets/{marketId}/quote.
| Field | Type | Description | |
|---|---|---|---|
| quote_id | string | required | Reference for your logs only — the order endpoint does not accept it. |
| market_id | string | required | Market the quote is for. |
| side | int | required | 1 = YES, 2 = NO. |
| shares | string | required | Shares this quote buys. |
| base_price | string | required | Fair probability before margin. |
| margin_add_pct | string | required | Margin added, percent (0–100). |
| price | string | required | Final price per share after margin. |
| cost | string | required | price × shares. |
| odds | string | required | Decimal odds equivalent. |
| currency | string | required | Quote currency. |
OrderView
Returned by POST /b2b/v1/orders.
| Field | Type | Description | |
|---|---|---|---|
| order_id | string | required | Booked order identifier. |
| market_id | string | required | Market the order is on. |
| side | int | required | 1 = YES, 2 = NO. |
| price | string | required | Executed price per share (probability). |
| qty | string | required | Shares allocated. |
| stake | string | required | Amount debited from the wallet. |
| currency | string | required | Order currency. |
| order_status | int | required | Lifecycle state: 2 debited, 3 filled, 4 rejected (see enums). |
| balance_after | string | required | Wallet balance after the debit. |
WalletView
Returned by GET /b2b/v1/wallet/balance.
| Field | Type | Description | |
|---|---|---|---|
| currency | string | required | Account currency. |
| available | string | required | Spendable balance. |
| frozen | string | required | Reserved / in-flight amount (0 in the seamless model). |
| balance | string | required | Total = available + frozen. |
WalletHookRequest
Body the operator POSTs to each of your four money hooks — /wallet/bet, /wallet/payout, /wallet/cashout and /wallet/refund. One shape for all four; biz echoes the path segment.
| Field | Type | Description | |
|---|---|---|---|
| merchant_id | string | required | Your merchant identifier. |
| player_id | string | required | The player's external_uid. |
| currency | string | required | ISO-4217 currency of the amount. |
| amount | string | required | Positive decimal, ≤2 dp. |
| idem_key | string | required | Idempotency key; reapply → same result. |
| market_id | string | optional | Originating market (reference). |
| order_id | string | optional | Originating order (reference). |
| biz | string | required | Always one of bet | payout | cashout | refund — echoes the hook path segment. Never absent, never empty. |
LaunchSession
Returned by POST /b2b/v1/auth/launch-token.
| Field | Type | Description | |
|---|---|---|---|
| launch_token | string | required | Single-use token redeemed by the game-client. |
| expires_in | int | required | Token lifetime in seconds — 60 in production; other environments may run longer. Read the field, do not hard-code it. |
| game_url | string | required | Embed URL: <game-client>/?lt=<launch_token>. |