Skip to main content
The orderbook is a public endpoint — no authentication required. You can read prices and liquidity using the SDK or REST API directly.
import { ClobClient } from "@polymarket/clob-client";

const client = new ClobClient("https://clob.polymarket.com", 137);

Get the Orderbook

Fetch the full orderbook for a token, including all resting bid and ask levels:
const book = await client.getOrderBook("TOKEN_ID");

console.log("Best bid:", book.bids[0]);
console.log("Best ask:", book.asks[0]);
console.log("Tick size:", book.tick_size);

Response

{
  "market": "0xbd31dc8a...",
  "asset_id": "52114319501245...",
  "timestamp": "2023-10-21T08:00:00Z",
  "bids": [
    { "price": "0.48", "size": "1000" },
    { "price": "0.47", "size": "2500" }
  ],
  "asks": [
    { "price": "0.52", "size": "800" },
    { "price": "0.53", "size": "1500" }
  ],
  "min_order_size": "5",
  "tick_size": "0.01",
  "neg_risk": false,
  "hash": "0xabc123..."
}
FieldDescription
marketCondition ID of the market
asset_idToken ID
bidsBuy orders sorted by price (highest first)
asksSell orders sorted by price (lowest first)
tick_sizeMinimum price increment for this market
min_order_sizeMinimum order size for this market
neg_riskWhether this is a multi-outcome (neg risk) market
hashHash of the orderbook state — use to detect changes

Prices

Get the best available price for buying or selling a token:
const buyPrice = await client.getPrice("TOKEN_ID", "BUY");
console.log("Best ask:", buyPrice.price); // Price you'd pay to buy

const sellPrice = await client.getPrice("TOKEN_ID", "SELL");
console.log("Best bid:", sellPrice.price); // Price you'd receive to sell

Midpoints

The midpoint is the average of the best bid and best ask. This is the price displayed on Polymarket as the market’s implied probability.
const midpoint = await client.getMidpoint("TOKEN_ID");
console.log("Midpoint:", midpoint.mid); // e.g., "0.50"
If the bid-ask spread is wider than $0.10, Polymarket displays the last traded price instead of the midpoint.

Spreads

The spread is the difference between the best ask and the best bid. Tighter spreads indicate more liquid markets.
const spread = await client.getSpread("TOKEN_ID");
console.log("Spread:", spread.spread); // e.g., "0.04"

Price History

Fetch historical price data for a token over various time intervals:
import { PriceHistoryInterval } from "@polymarket/clob-client";

const history = await client.getPricesHistory({
  market: "TOKEN_ID", // Note: this param is named "market" but takes a token ID
  interval: PriceHistoryInterval.ONE_DAY,
  fidelity: 60, // Data points every 60 minutes
});

// Each entry: { t: timestamp, p: price }
history.forEach((point) => {
  console.log(`${new Date(point.t * 1000).toISOString()}: ${point.p}`);
});
IntervalDescription
1hLast hour
6hLast 6 hours
1dLast day
1wLast week
1mLast month
maxAll available data
interval is relative to the current time. Use startTs / endTs for absolute time ranges. They are mutually exclusive — don’t combine them.

Estimate Fill Price

Calculate the effective price you’d pay for a market order of a given size, accounting for orderbook depth:
import { Side, OrderType } from "@polymarket/clob-client";

// What price would I pay to buy $500 worth?
const price = await client.calculateMarketPrice(
  "TOKEN_ID",
  Side.BUY,
  500, // dollar amount
  OrderType.FOK,
);

console.log("Estimated fill price:", price);
This walks the orderbook to estimate slippage. Useful for sizing market orders before submitting them.

Batch Requests

All orderbook queries have batch variants for fetching data across multiple tokens in a single request (up to 500 tokens):
SingleBatchREST
getOrderBook()getOrderBooks()POST /books
getPrice()getPrices()POST /prices
getMidpoint()getMidpoints()POST /midpoints
getSpread()getSpreads()POST /spreads
getLastTradePrice()getLastTradesPrices()
BookParams for batch orderbook requests accepts a token_id and an optional side parameter to filter by bid or ask side.
import { Side } from "@polymarket/clob-client";

// Fetch prices for multiple tokens
const prices = await client.getPrices([
  { token_id: "TOKEN_A", side: Side.BUY },
  { token_id: "TOKEN_B", side: Side.BUY },
]);
// Returns: { "TOKEN_A": { "BUY": "0.52" }, "TOKEN_B": { "BUY": "0.74" } }

Last Trade Price

Get the price and side of the most recent trade for a token:
const lastTrade = await client.getLastTradePrice("TOKEN_ID");
console.log(lastTrade.price, lastTrade.side);
// e.g., "0.52", "BUY"

Real-Time Updates

For live orderbook data, use the WebSocket API instead of polling. The market channel streams orderbook changes, price updates, and trade events in real time.

Connecting

const ws = new WebSocket(
  "wss://ws-subscriptions-clob.polymarket.com/ws/market",
);

ws.onopen = () => {
  ws.send(
    JSON.stringify({
      type: "market",
      assets_ids: ["TOKEN_ID"],
      custom_feature_enabled: true, // enables best_bid_ask, new_market, market_resolved events
    }),
  );
};

ws.onmessage = (event) => {
  const data = JSON.parse(event.data);
  switch (data.event_type) {
    case "book": // full orderbook snapshot
    case "price_change": // individual price level update
    case "last_trade_price": // new trade executed
    case "tick_size_change": // market tick size changed
    case "best_bid_ask": // top-of-book update (requires custom_feature_enabled)
    case "new_market": // new market created (requires custom_feature_enabled)
    case "market_resolved": // market resolved (requires custom_feature_enabled)
  }
};

Dynamic Subscribe and Unsubscribe

After connecting, you can change your subscriptions without reconnecting:
// Subscribe to additional tokens
ws.send(
  JSON.stringify({
    assets_ids: ["NEW_TOKEN_ID"],
    operation: "subscribe",
  }),
);

// Unsubscribe from tokens
ws.send(
  JSON.stringify({
    assets_ids: ["OLD_TOKEN_ID"],
    operation: "unsubscribe",
  }),
);

Event Types

EventTriggerKey Fields
bookOn subscribe + when a trade affects the bookbids[], asks[], hash, timestamp
price_changeNew order placed or order cancelledprice_changes[] with price, size, side, best_bid, best_ask
last_trade_priceTrade executedprice, side, size, fee_rate_bps
tick_size_changePrice hits >0.96 or < 0.04old_tick_size, new_tick_size
best_bid_askTop-of-book changesbest_bid, best_ask, spread
new_marketMarket createdquestion, assets_ids, outcomes
market_resolvedMarket resolvedwinning_asset_id, winning_outcome
best_bid_ask, new_market, and market_resolved require custom_feature_enabled: true in your subscription message.
The tick_size_change event is critical for trading bots. If the tick size changes and you continue using the old tick size, your orders will be rejected.

Next Steps