Python Client
Minimal example implementation of Python client to interact with Gameday exchange.
| Client | Use it for | Requires signing key |
|---|---|---|
GamedayClient | Typed models, side encoding, order building, and EIP-712 signing | Only for order actions |
Web3Client | On-chain reads plus allowance, cancel, and claim transactions | Yes |
ApiClient | Minimal REST calls with typed API errors | No |
encoding | Market side (token ID) encoding / decoding from uint256 representation | No |
The REST clients automatically unwrap the shared success envelope and raise structured exceptions for error responses. The typed client adds market-aware order helpers so users do not have to hand-roll side encoding or EIP-712 payloads.
These clients are intentionally small. They are meant to be a reference for your own implementation.
Getting started
Fetching available market collections.
import os
from eth_account import Account
from api.client import GamedayClient
from api.config import ClientConfig
# load your private key to sign orders
account = Account.from_key(os.getenv("YOUR_WALLET_KEY"))
config = ClientConfig(
base_url=https://gameday.markets/api,
auth_token=os.get_env("API_KEY"),
account=account,
chain=11155420
)
client = GamedayClient(config)
cl.get_collections()
>>> [{'entity': 'Bitcoin', 'market_count': 2}, {'entity': 'F1', 'market_count': 2}, {'entity': 'FIFA World Cup', 'market_count': 3}, {'entity': 'NBA', 'market_count': 2}]
Fetching markets
cl.get_markets("Bitcoin")
>>> [Market(market_name='BTCUSD price 2026-06-06', description='Event resolves to YES if BitMEX .BXBT index (bitmex.com/app/index/.BXBT) is greater than or equal to the target price on 2026-06-06 20:00 UTC.', description_hash='6909cec446e362e07db9e83def246319f8e2c9fe3d59c9016fa619abf1c0e68c', event_id=59284192173660553983829066293343914472327160798828592751200376623956234053690, settlement_type=<MarketType.OVERUNDER: 3>, n_outcomes=1, expiry=1780776000, currency='0x672f464846e86ce6fe0F2dF8358b8249A12439d8', version='ou_v2', address='0x1d93d964ce88eaeFE7d459B062EC848b458139d6', name_short='BTCUSD 20260606', start_time=1779875166, bet_type='price', display_status='0', display_priority='[]', candidate_outcomes=['64500', '65500', '66500', '67500', '68500', '69500', '70500', '71500', '72500', '73500', '74500', '75500', '76500', '77500', '78500', '79500', '80500', '81500', '62000', '62500', '63000', '63500', '64000', '65000', '66000', '67000', '68000', '69000', '70000', '71000', '72000'], status=1, resolution_state=0, outcome=[], entity='Bitcoin', volume=16000000)]
Submitting orders
For scalar outcome events, such as price markets, outcome is an integer value - one of candidate outcomes.
order = cl.build_order(
market="0x1d93d964ce88eaeFE7d459B062EC848b458139d6",
size=50*10e6, # 50 USDC
yes_no=True, # over/under (call/put) wrt strike price
outcome=67000, # strike price, as integer, only one of candidate outcomes accepted
price=5500, # price as basis points
)
signed_order = cl.sign_order(order) # sign EIP-712 data with provided key
cl.place_order(signed_order) # submit order to CLOB
For categorical markets, which resolve to one of preset candidate outcomes, outcome is an index of candidate outcomes array:
cl.get_market("0x6be27081bC2BF0F318BB9C62A098646Be8D1f730")
>>> Market(market_name='Group A: Mexico vs South Africa', description='FIFA World Cup 2026 Matchday 1, Group A match between Mexico and South Africa in Mexico City. Scheduled Start: Thursday, June 11, 2026 at 07:00 PM UTC', description_hash='7757962724999b28d09d68bbb2bb3b018f7ef853f5075801bf7db2666555b60b', event_id=18568566312947289722104530323130404698620178579483588220412103555084861387298, settlement_type=<MarketType.RANKED: 1>, n_outcomes=1, expiry=1781211600, currency='0x672f464846e86ce6fe0F2dF8358b8249A12439d8', version='ranked_v2', address='0x6be27081bC2BF0F318BB9C62A098646Be8D1f730', name_short='Mexico vs South Africa', start_time=1781204400, bet_type='winner', display_status='0', display_priority='[0,0,0]', candidate_outcomes=['Mexico', 'Draw', 'South Africa'], status=0, resolution_state=0, outcome=[], entity='FIFA World Cup', volume=10000000)
order = cl.build_order(
market="0x6be27081bC2BF0F318BB9C62A098646Be8D1f730",
size=50*10e6,
yes_no=True, # in favor or against selected outcome
outcome=0, # index of candidate outcomes: 0 = Mexico, 1 = Draw, 2 = South Africa
price=5500,
)
Fetching account data
# all orders
cl.get_orders()
>>> [Order(owner='0xF6206615a2b222dbA064B83Fc2449d5dBf057224', salt='PY-17805120871b487103e8126541', market='0x1d93d964ce88eaeFE7d459B062EC848b458139d6', side=21716317273191121794908309581631211478035604576498232614272661820087589735316, price=5700, size=400000000, expiry=0, signature='0x2bd51c5c592d41c928bef23e7607de831363fc3b036f84b67d325e3bc6705a5913db950e2f3bfe1b945edfc37c0cb2fab21e8cee43e952e9825fdc8f25d9cbdb1c', fill=0, timestamp=1780512087, market_name='BTCUSD 20260606', side_name='[68500]')]
# filter orders
cl.get_orders(
market="0x1d93d964ce88eaeFE7d459B062EC848b458139d6",
side=cl.get_market("0x1d93d964ce88eaeFE7d459B062EC848b458139d6").encode_side(True, 68500)
)
# get positions
cl.get_positions(
market=["0x676Ec3017c4A78f2aEdF0b0048C9915D1D215F61", "0x1d93d964ce88eaeFE7d459B062EC848b458139d6"],
side=[21714550426126343410578726284130468559519777092601356995314540213886297121540, "21716317273191121794908309581631211478035604576498232614272661820087589740316"]
)
>>> [Position(market='0x1d93d964ce88eaeFE7d459B062EC848b458139d6', balance=40000000, avg_price=0.65, claimable=0, market_name='BTCUSD 20260606', side=21714550426126343410578726284130468559519777092601356995314540213886297121540, side_name='[74500]', is_final=False, timestamp=0, expiry=1780776000, outcome=[], tx_hash=''), Position(market='0x1d93d964ce88eaeFE7d459B062EC848b458139d6', balance=16000000, avg_price=0.25, claimable=0, market_name='BTCUSD 20260606', side=21716317273191121794908309581631211478035604576498232614272661820087589740316, side_name='[73500]', is_final=False, timestamp=0, expiry=1780776000, outcome=[], tx_hash='')]
Side (Token ID) encoding
Encoding modules contains functions to manually encode and decode market side ERC 6909 Token ID. Market class instance also has encode_side method which performs additional encoding compatibility checks.
market = cl.get_market("0x1d93d964ce88eaeFE7d459B062EC848b458139d6")
market.encode_side(False, outcome_val=74500)
>>> 21714550426126343410578726284130468559519777092601356995314540213886297121540
If selected outcome is not within candidate outcomes, market encoder will throw an error:
market.encode_side(False, outcome_val=100000)
>>> MarketEncodingError: BTCUSD price 2026-06-06 : 66500: Outcome value must be within candidate outcomes for market type MarketType.OVERUNDER
Encoding module
import encoding
# BINARY markets only require yes/no flag
encoding.encode_side(encoding.MarketType.BINARY, yes=True)
>>> 5300541194335152988749892502228755547482451690626856874364818603877859328
# RANKED markets may have from 1 up to 30 outcome indices
encoding.encode_side(encoding.MarketType.RANKED, yes=False, outcome_idx=[1])
>>> 7240539271461818982632353158044480077861029009396286490382342212897155842049
# TOP markets may have up to 240 outcome indices
encoding.encode_side(encoding.MarketType.TOP, yes=False, outcome_idx=[0, 2, 3])
>>> 14484612237053194733923872911090445992753712986586324218680927638196896923661
# OVERUNDER, EXACT markets take single integer as outcome
encoding.encode_side(encoding.MarketType.OVERUNDER, yes=False, outcome_val=74500)
>>> 21714550426126343410578726284130468559519777092601356995314540213886297121540
# decode_side returns DecodedSide
encoding.decode_side(21714550426126343410578726284130468559519777092601356995314540213886297121540)
>>> DecodedSide(market_type=<MarketType.OVERUNDER: 3>, yes=False, n_outcomes=1, outcome_idx=None, outcome_val=74500, low_bound=None, high_bound=None)