Markets
Section titled “Markets”import { STX } from "@stxapp/stx-typescript";
const client = new STX();const page = await client.markets({ status: "open", limit: 5 });for (const market of page) { console.log(market.symbol, "last", market.last_traded_price, "bid", market.bids?.[0]?.price);}console.log("more pages:", page.hasMore);| Option | Meaning |
|---|---|
marketIds, eventIds |
One id or a list |
status |
One or a list, lowercase, e.g. "open"; see Market status |
trading |
true for only the markets accepting orders now, false for only those that are not |
sports, competitions |
One or a list |
sortBy, sortDirection |
e.g. sortBy: "event_start", sortDirection: "desc" |
limit, cursor |
Page size and the cursor from the previous page |
Filters combine with AND; a list filter matches any of its values. client.market(id) fetches one market and throws STXNotFoundException when there is none.
Pagination
Section titled “Pagination”A list method returns one Page: page.items, page.cursor (null on the last page), page.hasMore and page.length. A Page is iterable. To walk every page, use the iter* twin, which follows the cursor for you:
import { STX } from "@stxapp/stx-typescript";
const client = new STX();
let market;for await (const m of client.iterMarkets({ trading: true, sortBy: "event_start", sortDirection: "desc" })) { if (m.event_status === "scheduled") { market = m; break; }}console.log(market?.market_id, market?.symbol, market?.max_price);trading: true returns only the markets that accept orders now.
Or page by hand:
let page = await client.markets({ status: "open", limit: 100 });while (true) { for (const m of page) console.log(m.symbol); if (!page.hasMore) break; page = await client.markets({ status: "open", limit: 100, cursor: page.cursor! });}Events
Section titled “Events”const events = await client.events({ limit: 10 });for (const e of events) console.log(e.event_id, e.title, e.status);
for await (const e of client.iterEvents({ promoted: true })) console.log(e.title);events() filters on eventIds, sports, competitions, eventTypes, title, status and promoted, and sorts with sortBy and sortDirection.
Creating markets
Section titled “Creating markets”An app that STX has granted the markets.write scope can create player-prop markets on scheduled events, from an address on its IP allow-list. See Creating markets for the setup and the full list of outcomes.
import { AppScopes, OAuthClient } from "@stxapp/stx-typescript/oauth";import { Stats } from "@stxapp/stx-typescript";
const oauth = new OAuthClient({ clientId, clientSecret });const stx = oauth.appClient([AppScopes.EVENTS, AppScopes.MARKETS_WRITE]);
const roster = await stx.eventPlayers(eventId);const player = roster.teams[0].players[0];
const results = await stx.createMarkets(eventId, [ { playerId: player.player_id, stat: Stats.Basketball.POINTS, line: 18.5 }, { playerId: player.player_id, stat: Stats.Basketball.REBOUNDS, line: 4.5 },]);for (const r of results) console.log(r.status, r.status === "rejected" ? r.reason : r.market_id);- Lines must be positive and end in
.5:18.5is accepted;18,18.25,0and"18.5"come backrejectedwithinvalid_line. - Stats: an event accepts the stats
eventPlayers()(orstatsFor(event)) returns for it.Statslists them by sport for autocomplete. - Results come back one per market, in order:
created,exists(already listed, samemarket_id) orrejectedwith areason. Resending is safe. validate: truechecks players, stats and lines before sending, and returns failures asrejectedwithout a request. It reads the event’s players, so the token also needsevents.- Up to
MAX_MARKETS_PER_REQUEST(25) markets per call; more throwsTypeErrorbefore sending.
Live prices
Section titled “Live prices”bids and offers are a snapshot of the top of the book. To follow prices as they move, stream them; see WebSockets.

