> ## Documentation Index > Fetch the complete documentation index at: https://docs.polymarket.com/llms.txt > Use this file to discover all available pages before exploring further. # Orderbook > Reading the orderbook, prices, spreads, and midpoints The orderbook is a public endpoint — no authentication required. You can read prices and liquidity using the SDK or REST API directly. ```typescript TypeScript theme={null} import { ClobClient } from "@polymarket/clob-client"; const client = new ClobClient("https://clob.polymarket.com", 137); ``` ```python Python theme={null} from py_clob_client.client import ClobClient client = ClobClient("https://clob.polymarket.com", chain_id=137) ``` ```bash REST theme={null} # Base URL for all orderbook endpoints https://clob.polymarket.com ``` *** ## Get the Orderbook Fetch the full orderbook for a token, including all resting bid and ask levels: ```typescript TypeScript theme={null} 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); ``` ```python Python theme={null} book = client.get_order_book("TOKEN_ID") print("Best bid:", book["bids"][0]) print("Best ask:", book["asks"][0]) print("Tick size:", book["tick_size"]) ``` ```bash REST theme={null} curl "https://clob.polymarket.com/book?token_id=TOKEN_ID" ``` ### Response ```json theme={null} { "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..." } ``` | Field | Description | | ---------------- | --------------------------------------------------- | | `market` | Condition ID of the market | | `asset_id` | Token ID | | `bids` | Buy orders sorted by price (highest first) | | `asks` | Sell orders sorted by price (lowest first) | | `tick_size` | Minimum price increment for this market | | `min_order_size` | Minimum order size for this market | | `neg_risk` | Whether this is a multi-outcome (neg risk) market | | `hash` | Hash of the orderbook state — use to detect changes | *** ## Prices Get the best available price for buying or selling a token: ```typescript TypeScript theme={null} 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 ``` ```python Python theme={null} buy_price = client.get_price("TOKEN_ID", "BUY") print("Best ask:", buy_price["price"]) sell_price = client.get_price("TOKEN_ID", "SELL") print("Best bid:", sell_price["price"]) ``` ```bash REST theme={null} # Best price for buying (lowest ask) curl "https://clob.polymarket.com/price?token_id=TOKEN_ID&side=BUY" # Best price for selling (highest bid) curl "https://clob.polymarket.com/price?token_id=TOKEN_ID&side=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. ```typescript TypeScript theme={null} const midpoint = await client.getMidpoint("TOKEN_ID"); console.log("Midpoint:", midpoint.mid); // e.g., "0.50" ``` ```python Python theme={null} midpoint = client.get_midpoint("TOKEN_ID") print("Midpoint:", midpoint["mid"]) ``` ```bash REST theme={null} curl "https://clob.polymarket.com/midpoint?token_id=TOKEN_ID" ``` 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. ```typescript TypeScript theme={null} const spread = await client.getSpread("TOKEN_ID"); console.log("Spread:", spread.spread); // e.g., "0.04" ``` ```python Python theme={null} spread = client.get_spread("TOKEN_ID") print("Spread:", spread["spread"]) ``` ```bash REST theme={null} # Spreads use POST for batch requests curl -X POST "https://clob.polymarket.com/spreads" \ -H "Content-Type: application/json" \ -d '[{"token_id": "TOKEN_ID"}]' ``` *** ## Price History Fetch historical price data for a token over various time intervals: ```typescript TypeScript theme={null} 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}`); }); ``` ```python Python theme={null} history = client.get_prices_history( market="TOKEN_ID", # Note: this param is named "market" but takes a token ID interval="1d", fidelity=60, # Data points every 60 minutes ) for point in history: print(f"{point['t']}: {point['p']}") ``` ```bash REST theme={null} # By interval (relative to now) curl "https://clob.polymarket.com/prices-history?market=TOKEN_ID&interval=1d&fidelity=60" # By timestamp range curl "https://clob.polymarket.com/prices-history?market=TOKEN_ID&startTs=1697875200&endTs=1697961600" ``` | Interval | Description | | -------- | ------------------ | | `1h` | Last hour | | `6h` | Last 6 hours | | `1d` | Last day | | `1w` | Last week | | `1m` | Last month | | `max` | All 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: ```typescript TypeScript theme={null} 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); ``` ```python Python theme={null} from py_clob_client.clob_types import OrderType price = client.calculate_market_price( token_id="TOKEN_ID", side="BUY", amount=500, order_type=OrderType.FOK, ) print("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): | Single | Batch | REST | | --------------------- | ----------------------- | ----------------- | | `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. ```typescript TypeScript theme={null} 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" } } ``` ```python Python theme={null} prices = client.get_prices([ {"token_id": "TOKEN_A", "side": "BUY"}, {"token_id": "TOKEN_B", "side": "BUY"}, ]) ``` ```bash REST theme={null} curl -X POST "https://clob.polymarket.com/prices" \ -H "Content-Type: application/json" \ -d '[ {"token_id": "TOKEN_A", "side": "BUY"}, {"token_id": "TOKEN_B", "side": "BUY"} ]' ``` *** ## Last Trade Price Get the price and side of the most recent trade for a token: ```typescript TypeScript theme={null} const lastTrade = await client.getLastTradePrice("TOKEN_ID"); console.log(lastTrade.price, lastTrade.side); // e.g., "0.52", "BUY" ``` ```python Python theme={null} last_trade = client.get_last_trade_price("TOKEN_ID") print(last_trade["price"], last_trade["side"]) ``` *** ## 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 ```typescript theme={null} 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 / Unsubscribe After connecting, you can change your subscriptions without reconnecting: ```typescript theme={null} // 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 | Event | Trigger | Key Fields | | ------------------ | -------------------------------------------- | ---------------------------------------------------------------------- | | `book` | On subscribe + when a trade affects the book | `bids[]`, `asks[]`, `hash`, `timestamp` | | `price_change` | New order placed or order cancelled | `price_changes[]` with `price`, `size`, `side`, `best_bid`, `best_ask` | | `last_trade_price` | Trade executed | `price`, `side`, `size`, `fee_rate_bps` | | `tick_size_change` | Price hits >0.96 or \< 0.04 | `old_tick_size`, `new_tick_size` | | `best_bid_ask` | Top-of-book changes | `best_bid`, `best_ask`, `spread` | | `new_market` | Market created | `question`, `assets_ids`, `outcomes` | | `market_resolved` | Market resolved | `winning_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 Create and submit orders using the orderbook data Find token IDs for markets you want to trade