Skip to main content

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 Authorization header.
  • 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):

  1. Login:
    Manually request API KEY via /account page. Key is valid for 6 months.

  2. Use the Token:
    Include the token in the Authorization header 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 identifier
  • market: string (optional) — Market identifier
  • size: number (optional) — Number of trades
  • startTs: number (optional) — Start timestamp
  • endTs: 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:

  • price and size must match the regex ^\d+$ (only digits).
  • price must be an integer between 1 and 9999 (inclusive).
  • size must be an integer between 1e18 and 100000e18 (inclusive).
  • expiry is parsed as an integer if possible.
  • If any validation fails, an appropriate error message is returned.

Response:

  • 200 OK
    Order accepted
  • 400 Bad Request
    { "error": "Invalid JSON" }
    or
    { "error": "invalid price" }
    or
    { "error": "invalid size" }
    or
    { "error": "Market does not exist" }
    or
    {"error": "Order ID already exists" }
    or
    {"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:
    The side field 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 (from candidateOutcomes) 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

CodeMeaning
200Success
400Invalid input or parameters
401Authentication required/failed
404Resource not found
500Server error