API Reference
🚀 Get Started
Welcome to the Gameday API!
This API provides endpoints for market data, trading, balances, positions, and real-time updates via WebSocket.
General Overview
- REST Endpoints: All endpoints use standard HTTP methods (
GET,POST,DELETE) and return JSON responses. - Authentication: Protected endpoints require an API key (JWT token) in the
Authorizationheader. - WebSocket: Subscribe to channels for real-time orderbook and trade updates.
Authentication & API Key
To access protected endpoints (such as balances, positions, orders), you must first obtain an API key (JWT token):
-
Login:
Manually request API KEY via/accountpage. Key is valid for 6 months. -
Use the Token:
Include the token in theAuthorizationheader for all protected requests:Authorization: Bearer <API_KEY>
Example: Python Usage
import requests
headers = {"Authorization": f"Bearer {API_KEY}"}
balances = requests.get("https://gameday.exchange/api/balances", headers=headers).json()
print("Your balances:", balances)
📈 Market Data
Get Avalaible Collections
GET /collections
Get a list of entities with active markets.
Return Type:
type Collection = {
entity: string,
marketCount: number
}
Response:
200 OK[ /* Collection */ ]
Get Collections
GET /collections/:entity
Find all active markets for a particular entity (e.g., NBA, Bitcoin, F1).
Path Parameters:
entity:string— Entity identifier
Return Type:
type MarketParams = {
address: string;
eventId: string;
marketName: string;
descriptionHash: string;
candidateOutcomes: string;
expiry: string;
status: string;
outcomeType: string;
outcome: string;
isFinal: string;
isDisputed: string;
nameShort: string;
startTime: string;
description: string;
entity: string;
tags: string;
betType: string;
displayStatus: string;
displayPriority: string;
deployed: string;
txHash: string;
blockNumber: string;
blockHash: string;
deployedTs: string;
state: string;
volume: string;
}
Response:
200 OK[ /* MarketParams */ ]
Get Market Details
GET /market/:address
Retrieve details for a specific market.
Path Parameters:
address:string— Market address
Return Type:
MarketParams (see above)
Response:
200 OK{ /* MarketParams */ }404 Not Found{ "error": "Market does not exist" }
Get Orderbook
GET /orderbook/:address
Retrieve the orderbook for a market.
Path Parameters:
address:string— Market address
Return Type:
type BookState = {
market: string;
books: Record<string, Array<{ price: number; size: number }>>;
ts: number;
}
Response:
200 OK{ /* BookState */ }404 Not Found{ "error": "Market does not exist" }
Get Orderbooks by Entity
GET /orderbooks/:entity
Retrieve orderbooks for all markets under an entity.
Path Parameters:
entity:string— Entity identifier
Return Type:
type OrderbooksResponse = Array<BookState>
Response:
200 OK[ /* BookState */ ]
Get Trades
GET /trades
Retrieve trades by market or collection.
Query Parameters:
collection:string(optional) — Collection identifiermarket:string(optional) — Market identifiersize:number(optional) — Number of tradesstartTs:number(optional) — Start timestampendTs:number(optional) — End timestamp
Return Type:
type Trade = {
txhash: string;
market: string;
marketname: string;
amount: number;
price: number;
takerside: string;
takersidename: string;
timestamp: number;
}
Response:
200 OK[ /* Trade */ ]400 Bad Request{ "error": "Invalid parameter" }
🔐 User Data
Get Balances
GET /balances
Retrieve user balances.
Return Type:
type Balances = {
allowance: string;
balanceOf: string;
reserved: string;
}
Response:
200 OK{ "allowance": "string", "balanceOf": "string", "reserved": "string" }
Get Positions
GET /positions
Retrieve user positions.
Return Type:
type Position = {
market: string;
balance: string;
poolbalance: string;
rewardbalance: string;
marketname: string;
side: string;
sidename: string;
isfinal: boolean;
outcome: string;
outcometype: string;
txhash: string;
timestamp: number;
}
Response:
200 OK[ /* Position */ ]
Claim Position
GET /position/:market
Claim a position in a market.
Path Parameters:
market:string— Market address
Response:
200 OK(No body, just status)
Get Transactions
GET /transactions
Retrieve user transaction history.
Return Type:
type Transaction = {
txhash: string;
type: string;
market: string;
marketname: string;
side: string;
sidename: string;
price: number;
amount: string;
aggrside: string;
contractspend: string;
contractreceive: string;
currencyspend: string;
currencyreceive: string;
rewardfee: string;
poolnet: string;
timestamp: number;
}
Response:
200 OK[ /* Transaction */ ]
🔐 Orders
Get Orders
GET /orders
Retrieve user orders.
Return Type:
type Order = {
owner: string;
orderid: string;
market: string;
side: string;
price: number;
size: string;
fill: string;
expiry: number;
timestamp: number;
marketName: string;
sidename: string;
}
Response:
200 OK[ /* Order */ ]
Cancel Order
DELETE /orders/:order_id
Cancel an order.
Path Parameters:
order_id:string— Order identifier
Response:
200 OK(No body, just status)400 Bad Request{ "error": "Order cancel error" }
Place Order
POST /orders
Place a new order.
Request Body Type:
type OrderUI = {
orderid: string;
market: string;
side: string;
price: string; // must be a string representing an integer
size: string; // must be a string representing an integer
expiry: string;
}
Validation Logic:
priceandsizemust match the regex^\d+$(only digits).pricemust be an integer between1and9999(inclusive).sizemust be an integer between1e18and100000e18(inclusive).expiryis parsed as an integer if possible.- If any validation fails, an appropriate error message is returned.
Response:
200 OKOrder accepted400 Bad Requestor{ "error": "Invalid JSON" }or{ "error": "invalid price" }or{ "error": "invalid size" }or{ "error": "Market does not exist" }or{"error": "Order ID already exists" }{"error": "Insufficient balance"}
🔔 WebSocket
Subscribe to Channels
GET /ws/:channel
Establish a WebSocket connection for real-time updates.
Path Parameters:
channel:string— Comma-separated entity names
Response:
101 Switching Protocols(WebSocket connection established)
Once WebScoket connection is established, it is possible to:
subscribe
By sending subscribe message with op "subscribe" and comma separated entity names as args string
type WsOp = {
op: string
args: string
}
unsubscribe
By sending unsubscribe message with op "unsubscribe" and comma separated entity names as args string
WebSocket Message Types
Book Update
Sent when the orderbook for a market changes.
type BookUpdateMessage = {
event: "book_update";
market: string; // Market identifier
side: string; // Encoded side hexstring
state: string; // JSON stringified array of price/size objects
ts: number; // Timestamp (Unix seconds)
}
Example:
{
"event": "book_update",
"market": "0x1234",
"side": "0x0004",
"state": "[{\"price\": 123.45, \"size\": 100}]",
"ts": 1712345678
}
Trade
Sent when a trade is executed.
type TradeMessage = {
event: "trade";
txhash: string; // Transaction hash
market: string; // Market identifier
marketname: string; // Market name
amount: number; // Trade amount (erc20: amount / (10 ** decimals)))
price: number; // Trade price
takerside: string; // Encoded taker side
takersidename: string; // Decoded taker side name(s)
timestamp: number; // Unix timestamp
}
Example:
{
"event": "trade",
"txhash": "0xabc123...",
"market": "0x1234",
"marketname": "NBA Finals",
"amount": 10,
"price": 150,
"takerside": "0x01",
"takersidename": "[\"Lakers\"]",
"timestamp": 1712345678
}
🏁 Market Side Encoding
Understanding "side" in Gameday Markets
Gameday events can have multiple outcomes. For example, a Formula 1 race may have 20 possible winners.
Instead of deploying 20 separate market contracts, Gameday uses a single contract per event, allowing bets on any outcome or side.
- Side Encoding:
Thesidefield in Orders, Positions, and Transactions is encoded as a hex string using:eth.abi.encode([bool, int256[]])bool: Indicates YES (betting for) or NO (betting against) a specific outcome.int256[]: An array containing the outcome index (fromcandidateOutcomes) or a scalar value for markets with continuous outcomes.
Python Example: Encoding and Decoding side
from eth_abi import encode, decode
from web3 import Web3
# Example: Bet YES on driver #7 (index 6)
yes_no_flag = True
outcome_indices = [6]
# Encode side
side_bytes = encode(["bool", "int256[]"], [yes_no_flag, outcome_indices])
side_hex = Web3.to_hex(side_bytes)
print("Encoded side hex:", side_hex)
# Decode side
decoded_flag, decoded_indices = decode(["bool", "int256[]"], Web3.to_bytes(hexstr=side_hex))
print("Decoded YES/NO flag:", decoded_flag) # True for YES, False for NO
print("Decoded outcome indices:", decoded_indices) # List of outcome indices or scalar values
⚠️ Error Codes
| Code | Meaning |
|---|---|
| 200 | Success |
| 400 | Invalid input or parameters |
| 401 | Authentication required/failed |
| 404 | Resource not found |
| 500 | Server error |