Skip to main content
There are two ways to fetch odds depending on what you need:
EndpointUse when
GET /ordersYou need the full orderbook — all active orders, sizes, and individual order details
GET /orders/odds/bestYou only need the current best price for each outcome
All odds returned by the API are from the maker’s perspective. To get the taker odds on the opposite outcome, use: takerOdds = 1 - percentageOdds / 10^20. For example, if a maker is asking for 51% on outcome 1, a taker gets outcome 2 at 49%.

GET /orders

Use this when you need to inspect full order details — available sizes, fill status, or depth across both sides of a market. You can fetch orders for multiple markets at once, all orders for a specific event, or all orders posted by a specific maker address. See the full parameter reference →.
curl "https://api.sx.bet/orders?marketHashes=0x1a46..."
Like the percentageOdds value, totalBetSize and fillAmount are from the maker’s perspective. To calculate available taker liquidity, use: remainingTakerSpace = (totalBetSize - fillAmount) * 10^20 / percentageOdds - (totalBetSize - fillAmount)

GET /orders/odds/best

Use this when you only need the best available price on each side — for example, to check odds before placing a fill (see Filling Orders) or to scan for value across a league. Note that this endpoint only returns the best price, not available liquidity at that price. If you need to know how much you can fill at those odds, use GET /orders to fetch the full orderbook. See the full parameter reference →.
curl "https://api.sx.bet/orders/odds/best?marketHashes=0xbe62...&baseToken=0x6629..."

Real-time best odds

Subscribe to best_odds:global to receive live best odds updates. Each message is a complete replacement for that market/outcome — not a delta. The channel is global, covering all markets and tokens in a single subscription. Subscribe first, then seed from REST inside the subscribed handler:
const sub = client.newSubscription("best_odds:global");

sub.on("publication", (ctx) => {
  for (const update of ctx.data) {
    const key = `${update.marketHash}:${update.isMakerBettingOutcomeOne}`;
    const existing = state[key];
    if (existing && update.updatedAt <= existing.updatedAt) continue; // guard against out-of-order delivery
    state[key] = update;
  }
});

sub.on("subscribed", async () => {
  // Re-seeds on every connect — REST uses outcomeOne/outcomeTwo; WS uses isMakerBettingOutcomeOne
  const res = await fetch(`https://api.sx.bet/orders/odds/best?marketHashes=${marketHashes.join(",")}&baseToken=${baseToken}`);
  const { data } = await res.json();
  for (const market of data.bestOdds) {
    state[`${market.marketHash}:true`] = { marketHash: market.marketHash, isMakerBettingOutcomeOne: true, percentageOdds: market.outcomeOne.percentageOdds, updatedAt: market.outcomeOne.updatedAt };
    state[`${market.marketHash}:false`] = { marketHash: market.marketHash, isMakerBettingOutcomeOne: false, percentageOdds: market.outcomeTwo.percentageOdds, updatedAt: market.outcomeTwo.updatedAt };
  }
});

sub.subscribe();
best_odds:global has no server-side history — recovery across reconnects is not available. The subscribed handler re-seeds from REST on every connect, keeping state consistent.
For payload field definitions, see Best Odds →.

Real-time orderbook

For a live orderbook, subscribe to order_book:market_{marketHash} with positioned: true, recoverable: true. Centrifugo’s history recovery handles the subscribe-to-fetch race condition automatically — you don’t need to manually buffer messages. See Real-time Data → Snapshot + subscribe pattern for the full pattern and code example.