Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.sportsxapp.com/llms.txt

Use this file to discover all available pages before exploring further.

The SDK’s market-data surface is intentionally narrow. The canonical entry is client.markets() — it returns a Page[MarketInfo]: a list-like value carrying the items plus the server’s total count, so you can decide whether to fetch more without a second round trip.
Every response is a typed Pydantic v2 model — you get attribute access, IDE autocomplete, and validation for free. Call .model_dump() on any model if you need a plain dict.

List markets

from stx import STX, Selection

client = STX(region="ontario", env="staging")
client.login(params={})

page = client.markets(
    params={"input": {"limit": 50}},
    selections=Selection("market_id", "status", "title"),
)
print(f"showing {len(page)} of {page.count}")
for market in page:
    print(market.market_id, market.status, market.title)
page iterates MarketInfo items; page.count is the server’s total across the unpaginated query. Fields not in the Selection are None on each item.

Filter knobs

MarketInfosInput supports several filters; combine them freely:
page = client.markets(
    params={
        "input": {
            "status": "OPEN",          # StatusEnum: OPEN | PRE_OPEN | CLOSED | RESULTED | ...
            "trading": "TRUE",          # TradingEnum: TRUE = "open and tradable"
            "sports": ["Soccer"],
            "limit": 25,
        }
    },
    selections=Selection("market_id", "title"),
)
Common filter recipes:
GoalFilter
Just the strict tradable set{"status": "OPEN", "trading": "TRUE"}
Specific markets by id{"market_ids": ["mkt_a", "mkt_b"]}
One sport, paginated{"sports": ["Soccer"], "limit": 50}
Keyword regex{"keyword_regex": "^NBA"}
Filter taxonomy{"filter_by": "ACTIVE"} (uses MarketFilterEnum)

Get specific markets by id

page = client.markets(
    params={"input": {"market_ids": ["mkt_8f3...", "mkt_4a2..."]}},
    selections=Selection("market_id", "title", "status", "price"),
)
markets = list(page)
When market_ids is set, limit is ignored.

Shaping the response

GraphQL’s killer feature over REST: you ask only for the fields you need. Pass a flat Selection(...) of the per-market fields you want — the SDK auto-injects the wrapper layer for you:
from stx import Selection

page = client.markets(
    selections=Selection("market_id", "status"),
)
# ~1 KB per 100 markets
For list queries that return 100+ items, the narrow form is 10–30× smaller on the wire. Always pass an explicit Selection in production code.

Presets

Canned selections for common shapes — import from stx:
from stx import STX, PRESETS, Selection

client = STX(region="ontario", env="staging")
client.login(params={})

page = client.markets(selections=PRESETS.MARKET_MINIMAL)
# PRESETS.MARKET_MINIMAL  → market_id, status
# PRESETS.MARKET_BASIC    → + title, sport, competition, price, probability, volume24h
# PRESETS.MARKET_TRADING  → + price_change24h, last_traded_price, timestamp

Paging shape

client.markets() returns a Page[MarketInfo]:
  • Iterable — for m in page: ...
  • Indexable + sliceable — page[0], page[:10]
  • len(page) — the items in this page
  • page.count — the server’s total across the unpaginated query
page = client.markets(params={"input": {"limit": 25}})
print(f"loaded {len(page)} of {page.count} markets")
first_ten = page[:10]

Paginating large result sets

limit caps each call. Use page.count to know when to stop:
def iter_all_markets(client, page_size=200):
    """Yield every MarketInfo, paged through the server. Trade off
    page_size against latency — 200 is a reasonable default."""
    offset = 0
    while True:
        page = client.markets(
            params={"input": {"limit": page_size}},
            selections=Selection("market_id", "title", "status"),
        )
        if not len(page):
            return
        yield from page
        offset += len(page)
        if offset >= (page.count or 0):
            return

client = STX(region="ontario", env="staging")
client.login(params={})
for market in iter_all_markets(client):
    ...
For very large bulk pulls, use AsyncSTX with asyncio.gather to parallelize pages — see Async.

Settlements

market_settlements returns the settlement trail for a specific market. trades_for_settlement drills into the trades that contributed to a single settlement event:
settlements = client.market_settlements(
    params={"market_id": "mkt_8f3...", "pagination": {"page": 0, "limit": 20}},
    selections=Selection("id", "amount", "time"),
)

# Drill into one
trades = client.trades_for_settlement(
    params={"settlement_id": settlements[0].id},
    selections=Selection("trades", "summary"),
)

Per-market account stats

account_market_stats returns your trading footprint per market — positions, fees paid, contracts settled. Useful for reconciliation + reporting:
stats = client.account_market_stats(
    params={"pagination": {"page": 0, "limit": 50}},
    selections=Selection(
        "market_id", "contracts_settled", "total_fees", "updated_at"
    ),
)
for s in stats:
    print(s.market_id, s.contracts_settled, s.total_fees)

Error handling

Market queries are mostly idempotent — the SDK’s default retry policy handles transient STXTransportException and STXRateLimitException automatically. See Errors & retries.

Next

Trading

Place orders, fetch positions, and manage fills.

WebSockets

Subscribe to live market updates over Phoenix channels.