Skip to content

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.

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! });
}
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.

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.5 is accepted; 18, 18.25, 0 and "18.5" come back rejected with invalid_line.
  • Stats: an event accepts the stats eventPlayers() (or statsFor(event)) returns for it. Stats lists them by sport for autocomplete.
  • Results come back one per market, in order: created, exists (already listed, same market_id) or rejected with a reason. Resending is safe.
  • validate: true checks players, stats and lines before sending, and returns failures as rejected without a request. It reads the event’s players, so the token also needs events.
  • Up to MAX_MARKETS_PER_REQUEST (25) markets per call; more throws TypeError before sending.

bids and offers are a snapshot of the top of the book. To follow prices as they move, stream them; see WebSockets.

v1.5.9Changelogllms.txtllms-full.txt