Skip to main content
Stream public market data as prices, books, trades, candles, tickers, and market statistics change.
Private order, fill, and account-state reconciliation is covered in Reconcile Trade State.
Start with the stream that matches the view you are building. Subscribe to the updates you need, read events while the view is active, then stop the stream when the view no longer needs live data.
Subscribe from a PublicClient and iterate over the merged event stream.
import { createPublicClient } from "@polymarket/client";

const client = createPublicClient();

const stream = await client.subscribe([
  { topic: "perps.bbo", instrumentId: 1 },
  { topic: "perps.trades", instrumentId: 1 },
]);

for await (const event of stream) {
  switch (event.type) {
    case "bbo":
      // event: PerpsBboEvent
      break;
    case "trade":
      // event: PerpsTradeEvent
      break;
  }

  if (shouldClose) {
    await stream.close();
  }
}
The stream yields typed events for each subscription and can be closed when the live view no longer needs updates.

Best Bid and Offer

Use best bid and offer updates for top-of-book quotes.
Subscribe to best bid and offer updates for one instrument.
const bbo = await client.subscribe([{ topic: "perps.bbo", instrumentId: 1 }]);

for await (const event of bbo) {
  // event: PerpsBboEvent
}
After subscribing, the stream yields PerpsBboEvent objects like this.
type PerpsBboEvent = {
  topic: "perps.bbo";
  type: "bbo";
  channel: string;
  timestamp: number;
  sequence: number;
  payload: {
    instrumentId: number;
    bidPrice: string;
    bidQuantity: string;
    askPrice: string;
    askQuantity: string;
  };
};

Order Book

Use order book updates for depth across bid and ask price levels.
Subscribe to order book updates for one instrument.
const book = await client.subscribe([{ topic: "perps.book", instrumentId: 1 }]);

for await (const event of book) {
  // event: PerpsBookEvent
}
After subscribing, the stream yields PerpsBookEvent objects like this.
type PerpsBookEvent = {
  topic: "perps.book";
  type: "book";
  channel: string;
  timestamp: number;
  sequence: number;
  payload: {
    instrumentId: number;
    bids: Array<{ price: string; quantity: string }>;
    asks: Array<{ price: string; quantity: string }>;
  };
};

Trades

Use trades to update recent-print lists, last-trade displays, or execution-based analytics.
Subscribe to public trade updates for one instrument.
const trades = await client.subscribe([
  { topic: "perps.trades", instrumentId: 1 },
]);

for await (const event of trades) {
  // event: PerpsTradeEvent
}
After subscribing, the stream yields PerpsTradeEvent objects like this.
type PerpsTradeEvent = {
  topic: "perps.trades";
  type: "trade";
  channel: string;
  timestamp: number;
  sequence: number;
  payload: {
    tradeId: number;
    instrumentId: number;
    side: "long" | "short";
    price: string;
    quantity: string;
    timestamp: number;
    hash?: string;
  };
};

Tickers

Use ticker updates for the current mark, index, last price, open interest, and funding state.
Subscribe to ticker updates for one instrument or all active instruments.
const tickers = await client.subscribe([
  { topic: "perps.tickers", instrumentId: 1 },
]);
for await (const event of tickers) {
  // event: PerpsTickerEvent
}
Omit instrumentId to subscribe to ticker updates for all active instruments.After subscribing, the stream yields PerpsTickerEvent objects like this.
type PerpsTickerEvent = {
  topic: "perps.tickers";
  type: "ticker";
  channel: string;
  timestamp: number;
  sequence: number;
  payload: {
    instrumentId: number;
    indexPrice: string;
    markPrice: string;
    lastPrice: string;
    midPrice: string;
    openInterest: string;
    fundingRate: string;
    nextFunding: number;
  };
};

Statistics

Use statistics for 24-hour volume, opening price, and the rolling kline window.
Subscribe to 24-hour statistics for one instrument or all active instruments.
const statistics = await client.subscribe([
  { topic: "perps.statistics", instrumentId: 1 },
]);
for await (const event of statistics) {
  // event: PerpsStatisticEvent
}
Omit instrumentId to subscribe to statistics updates for all active instruments.After subscribing, the stream yields PerpsStatisticEvent objects like this.
type PerpsStatisticEvent = {
  topic: "perps.statistics";
  type: "statistic";
  channel: string;
  timestamp: number;
  sequence: number;
  payload: {
    instrumentId: number;
    volume: string;
    openPrice: string;
    klines: Array<{
      timestamp: number;
      open: string;
      high: string;
      low: string;
      close: string;
      volume: string;
      trades: number;
    }>;
  };
};

Candles

Use candles to update charts with live OHLCV data.
Subscribe to candle updates for one instrument and interval.
import { PerpsKlineInterval } from "@polymarket/client";

const candles = await client.subscribe([
  {
    topic: "perps.candles",
    instrumentId: 1,
    interval: PerpsKlineInterval.OneMinute,
  },
]);

for await (const event of candles) {
  // event: PerpsCandleEvent
}
The public stream supports 1m, 5m, 15m, 1h, 4h, 1d, and 1w candle intervals.After subscribing, the stream yields PerpsCandleEvent objects like this.
type PerpsCandleEvent = {
  topic: "perps.candles";
  type: "candle";
  channel: string;
  timestamp: number;
  sequence: number;
  payload: {
    instrumentId: number;
    interval: "1m" | "5m" | "15m" | "1h" | "4h" | "1d" | "1w";
    candles: Array<{
      timestamp: number;
      open: string;
      high: string;
      low: string;
      close: string;
      volume: string;
      trades: number;
    }>;
  };
};