> ## 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.

# Real-Time Data

> Keep market data current with Polymarket's real-time feeds.

Use Polymarket's real-time feeds to react as market conditions and related data
change. They keep the public market data your application depends on current
without repeated polling. For authenticated order and trade updates, see
[Real-Time Order Updates](/trading/realtime-order-updates).

## Market Stream

Use the market stream to keep your application in sync with changes to a
market's order book and trading state.

<Tabs>
  <Tab title="TypeScript">
    The unified SDK uses `assetId` for an outcome's trading identifier: a token
    ID for a CTF market or a position ID for a Polymarket Protocol V2 market.
    Use the identifier exposed for that outcome.

    Given a `PublicClient` or `SecureClient`, subscribe to the `market` topic with one or
    more outcome IDs:

    ```ts theme={null}
    const assetId = "<asset_id>";

    const stream = await client.subscribe([
      {
        topic: "market",
        assetIds: [assetId],
      },
    ]);

    for await (const event of stream) {
      switch (event.type) {
        case "book":
          // event: MarketBookEvent
          break;
        case "price_change":
          // event: MarketPriceChangeEvent
          break;
        case "last_trade_price":
          // event: MarketLastTradePriceEvent
          break;
        case "tick_size_change":
          // event: MarketTickSizeChangeEvent
          break;
      }
    }
    ```

    <Accordion title="Standard Market Events">
      #### Order Book

      <CodeGroup>
        ```ts MarketBookEvent Type theme={null}
        type OrderBookLevel = {
          price: DecimalString;
          size: DecimalString;
        };

        type MarketBookEvent = {
          topic: "market";
          type: "book";
          payload: {
            conditionId: ConditionId;
            assetId: ClobAssetId;
            bids: OrderBookLevel[];
            asks: OrderBookLevel[];
            hash?: string | null;
            timestamp?: string | null;
            minOrderSize?: DecimalString | null;
            tickSize?: DecimalString | null;
            negRisk?: boolean | null;
            lastTradePrice?: DecimalString | null;
          };
        };
        ```

        ```json MarketBookEvent Example theme={null}
        {
          "topic": "market",
          "type": "book",
          "payload": {
            "conditionId": "0x747dc809fb79e1b05be09c42d6179459a58de2ef3e40f02484a4e1260f741f75",
            "assetId": "107505882767731489358349912513945399560393482969656700824895970500493757150417",
            "bids": [{ "price": "0.08", "size": "33343.4" }],
            "asks": [{ "price": "0.09", "size": "163939.58" }],
            "hash": "0xabc123…",
            "timestamp": "1782753357257"
          }
        }
        ```
      </CodeGroup>

      #### Price Change

      <CodeGroup>
        ```ts MarketPriceChangeEvent Type theme={null}
        type PriceChange = {
          assetId: ClobAssetId;
          price: DecimalString;
          size: DecimalString;
          side: OrderSide;
          hash?: string | null;
          bestBid?: DecimalString | null;
          bestAsk?: DecimalString | null;
        };

        type MarketPriceChangeEvent = {
          topic: "market";
          type: "price_change";
          payload: {
            conditionId: ConditionId;
            priceChanges: PriceChange[];
            timestamp?: string | null;
          };
        };
        ```

        ```json MarketPriceChangeEvent Example theme={null}
        {
          "topic": "market",
          "type": "price_change",
          "payload": {
            "conditionId": "0x747dc809fb79e1b05be09c42d6179459a58de2ef3e40f02484a4e1260f741f75",
            "priceChanges": [
              {
                "assetId": "107505882767731489358349912513945399560393482969656700824895970500493757150417",
                "price": "0.08",
                "size": "33343.4",
                "side": "BUY",
                "hash": "56621a121a47ed9333273e21c83b660cff37ae50",
                "bestBid": "0.08",
                "bestAsk": "0.09"
              }
            ],
            "timestamp": "1782753357257"
          }
        }
        ```
      </CodeGroup>

      #### Last Trade Price

      <CodeGroup>
        ```ts MarketLastTradePriceEvent Type theme={null}
        type MarketLastTradePriceEvent = {
          topic: "market";
          type: "last_trade_price";
          payload: {
            conditionId: ConditionId;
            assetId: ClobAssetId;
            price: DecimalString;
            size?: DecimalString | null;
            feeRateBps?: DecimalString | null;
            side: OrderSide;
            timestamp?: string | null;
            transactionHash?: string | null;
          };
        };
        ```

        ```json MarketLastTradePriceEvent Example theme={null}
        {
          "topic": "market",
          "type": "last_trade_price",
          "payload": {
            "conditionId": "0x747dc809fb79e1b05be09c42d6179459a58de2ef3e40f02484a4e1260f741f75",
            "assetId": "107505882767731489358349912513945399560393482969656700824895970500493757150417",
            "price": "0.08",
            "size": "219.217767",
            "feeRateBps": "0",
            "side": "SELL",
            "timestamp": "1782753357257",
            "transactionHash": "0xeeefff…"
          }
        }
        ```
      </CodeGroup>

      #### Tick Size Change

      <CodeGroup>
        ```ts MarketTickSizeChangeEvent Type theme={null}
        type MarketTickSizeChangeEvent = {
          topic: "market";
          type: "tick_size_change";
          payload: {
            conditionId: ConditionId;
            assetId: ClobAssetId;
            oldTickSize?: DecimalString | null;
            newTickSize: DecimalString;
            timestamp?: string | null;
          };
        };
        ```

        ```json MarketTickSizeChangeEvent Example theme={null}
        {
          "topic": "market",
          "type": "tick_size_change",
          "payload": {
            "conditionId": "0x747dc809fb79e1b05be09c42d6179459a58de2ef3e40f02484a4e1260f741f75",
            "assetId": "107505882767731489358349912513945399560393482969656700824895970500493757150417",
            "oldTickSize": "0.01",
            "newTickSize": "0.001",
            "timestamp": "1782753357257"
          }
        }
        ```
      </CodeGroup>
    </Accordion>

    Enable `customFeatureEnabled` to include top-of-book and market lifecycle
    updates:

    ```ts theme={null}
    const stream = await client.subscribe([
      {
        topic: "market",
        assetIds: [assetId],
        customFeatureEnabled: true,
      },
    ]);

    for await (const event of stream) {
      switch (event.type) {
        case "book":
          // event: MarketBookEvent
          break;
        case "price_change":
          // event: MarketPriceChangeEvent
          break;
        case "last_trade_price":
          // event: MarketLastTradePriceEvent
          break;
        case "tick_size_change":
          // event: MarketTickSizeChangeEvent
          break;
        case "best_bid_ask":
          // event: MarketBestBidAskEvent
          break;
        case "new_market":
          // event: NewMarketEvent
          break;
        case "market_resolved":
          // event: MarketResolvedEvent
          break;
      }
    }
    ```

    <Accordion title="Additional Market Events">
      #### Best Bid and Ask

      <CodeGroup>
        ```ts MarketBestBidAskEvent Type theme={null}
        type MarketBestBidAskEvent = {
          topic: "market";
          type: "best_bid_ask";
          payload: {
            conditionId: ConditionId;
            assetId: ClobAssetId;
            bestBid?: DecimalString | null;
            bestAsk?: DecimalString | null;
            spread?: DecimalString | null;
            timestamp?: string | null;
          };
        };
        ```

        ```json MarketBestBidAskEvent Example theme={null}
        {
          "topic": "market",
          "type": "best_bid_ask",
          "payload": {
            "conditionId": "0x747dc809fb79e1b05be09c42d6179459a58de2ef3e40f02484a4e1260f741f75",
            "assetId": "107505882767731489358349912513945399560393482969656700824895970500493757150417",
            "bestBid": "0.08",
            "bestAsk": "0.09",
            "spread": "0.01",
            "timestamp": "1782753357257"
          }
        }
        ```
      </CodeGroup>

      #### New Market

      <CodeGroup>
        ```ts NewMarketEvent Type theme={null}
        type NewMarketEvent = {
          topic: "market";
          type: "new_market";
          payload: {
            id: string;
            question?: string | null;
            market: string;
            slug?: string | null;
            description?: string | null;
            assetIds?: ClobAssetId[] | null;
            outcomes?: string[] | null;
            eventMessage?: {
              id: string;
              ticker?: string | null;
              slug?: string | null;
              title?: string | null;
              description?: string | null;
            } | null;
            timestamp?: string | null;
            tags?: string[] | null;
            conditionId?: ConditionId | null;
            active?: boolean | null;
            clobTokenIds?: string[] | null;
            sportsMarketType?: string | null;
            line?: DecimalString | null;
            gameStartTime?: IsoDateTimeString | null;
            orderPriceMinTickSize?: DecimalString | null;
            groupItemTitle?: string | null;
            takerBaseFee?: DecimalString | null;
            feesEnabled?: boolean | null;
            feeSchedule?: unknown;
          };
        };
        ```

        ```json NewMarketEvent Example theme={null}
        {
          "topic": "market",
          "type": "new_market",
          "payload": {
            "id": "123456",
            "market": "0x747dc809fb79e1b05be09c42d6179459a58de2ef3e40f02484a4e1260f741f75",
            "question": "Will the US confirm that aliens exist before 2027?",
            "slug": "will-the-us-confirm-that-aliens-exist-before-2027",
            "assetIds": [
              "107505882767731489358349912513945399560393482969656700824895970500493757150417",
              "7305630249804085635496399869905769372294302716159034447326228509068694952392"
            ],
            "outcomes": ["Yes", "No"],
            "active": true,
            "timestamp": "1782753357257"
          }
        }
        ```
      </CodeGroup>

      #### Market Resolved

      <CodeGroup>
        ```ts MarketResolvedEvent Type theme={null}
        type MarketResolvedEvent = {
          topic: "market";
          type: "market_resolved";
          payload: {
            id: string;
            conditionId: ConditionId;
            assetIds?: ClobAssetId[] | null;
            winningAssetId?: ClobAssetId | null;
            winningOutcome?: string | null;
            eventMessage?: {
              id: string;
              ticker?: string | null;
              slug?: string | null;
              title?: string | null;
              description?: string | null;
            } | null;
            timestamp?: string | null;
            tags?: string[] | null;
          };
        };
        ```

        ```json MarketResolvedEvent Example theme={null}
        {
          "topic": "market",
          "type": "market_resolved",
          "payload": {
            "id": "123456",
            "conditionId": "0x747dc809fb79e1b05be09c42d6179459a58de2ef3e40f02484a4e1260f741f75",
            "assetIds": [
              "107505882767731489358349912513945399560393482969656700824895970500493757150417",
              "7305630249804085635496399869905769372294302716159034447326228509068694952392"
            ],
            "winningAssetId": "107505882767731489358349912513945399560393482969656700824895970500493757150417",
            "winningOutcome": "Yes",
            "timestamp": "1782753357257"
          }
        }
        ```
      </CodeGroup>
    </Accordion>
  </Tab>

  <Tab title="Python">
    The unified SDK uses `asset_id` for an outcome's trading identifier: a token
    ID for a CTF market or a position ID for a Polymarket Protocol V2 market.
    Use the identifier exposed for that outcome.

    Given an `AsyncPublicClient` or `AsyncSecureClient`, subscribe to the market
    stream with a `MarketSpec` containing one or more outcome IDs:

    ```python theme={null}
    from polymarket.streams import MarketSpec

    asset_id = "<asset_id>"

    async with await client.subscribe(
        MarketSpec(asset_ids=[asset_id]),
    ) as stream:
        async for event in stream:
            if event.type == "book":
                ...  # event: MarketBookEvent
            elif event.type == "price_change":
                ...  # event: MarketPriceChangeEvent
            elif event.type == "last_trade_price":
                ...  # event: MarketLastTradePriceEvent
            elif event.type == "tick_size_change":
                ...  # event: MarketTickSizeChangeEvent
    ```

    <Accordion title="Standard Market Events">
      #### Order Book

      <CodeGroup>
        ```python MarketBookEvent Type theme={null}
        class OrderBookLevel:
            price: Decimal
            size: Decimal

        class MarketBookPayload:
            condition_id: ConditionId
            asset_id: ClobAssetId
            bids: tuple[OrderBookLevel, ...]
            asks: tuple[OrderBookLevel, ...]
            hash: str | None
            timestamp: datetime | None
            min_order_size: Decimal | None
            tick_size: Decimal | None
            neg_risk: bool | None
            last_trade_price: Decimal | None

        class MarketBookEvent:
            topic: Literal["market"]
            type: Literal["book"]
            payload: MarketBookPayload
        ```

        ```json MarketBookEvent Example theme={null}
        {
          "topic": "market",
          "type": "book",
          "payload": {
            "condition_id": "0x747dc809fb79e1b05be09c42d6179459a58de2ef3e40f02484a4e1260f741f75",
            "asset_id": "107505882767731489358349912513945399560393482969656700824895970500493757150417",
            "bids": [{ "price": "0.08", "size": "33343.4" }],
            "asks": [{ "price": "0.09", "size": "163939.58" }],
            "hash": "0xabc123…",
            "timestamp": "2026-06-29T17:15:57.257000Z"
          }
        }
        ```
      </CodeGroup>

      #### Price Change

      <CodeGroup>
        ```python MarketPriceChangeEvent Type theme={null}
        class PriceChange:
            asset_id: ClobAssetId
            price: Decimal
            size: Decimal
            side: Literal["BUY", "SELL"]
            hash: str | None
            best_bid: Decimal | None
            best_ask: Decimal | None

        class MarketPriceChangePayload:
            condition_id: ConditionId
            price_changes: tuple[PriceChange, ...]
            timestamp: datetime | None

        class MarketPriceChangeEvent:
            topic: Literal["market"]
            type: Literal["price_change"]
            payload: MarketPriceChangePayload
        ```

        ```json MarketPriceChangeEvent Example theme={null}
        {
          "topic": "market",
          "type": "price_change",
          "payload": {
            "condition_id": "0x747dc809fb79e1b05be09c42d6179459a58de2ef3e40f02484a4e1260f741f75",
            "price_changes": [
              {
                "asset_id": "107505882767731489358349912513945399560393482969656700824895970500493757150417",
                "price": "0.08",
                "size": "33343.4",
                "side": "BUY",
                "hash": "56621a121a47ed9333273e21c83b660cff37ae50",
                "best_bid": "0.08",
                "best_ask": "0.09"
              }
            ],
            "timestamp": "2026-06-29T17:15:57.257000Z"
          }
        }
        ```
      </CodeGroup>

      #### Last Trade Price

      <CodeGroup>
        ```python MarketLastTradePriceEvent Type theme={null}
        class MarketLastTradePricePayload:
            condition_id: ConditionId
            asset_id: ClobAssetId
            price: Decimal
            size: Decimal | None
            side: Literal["BUY", "SELL"]
            fee_rate_bps: Decimal | None
            transaction_hash: str | None
            timestamp: datetime | None

        class MarketLastTradePriceEvent:
            topic: Literal["market"]
            type: Literal["last_trade_price"]
            payload: MarketLastTradePricePayload
        ```

        ```json MarketLastTradePriceEvent Example theme={null}
        {
          "topic": "market",
          "type": "last_trade_price",
          "payload": {
            "condition_id": "0x747dc809fb79e1b05be09c42d6179459a58de2ef3e40f02484a4e1260f741f75",
            "asset_id": "107505882767731489358349912513945399560393482969656700824895970500493757150417",
            "price": "0.08",
            "size": "219.217767",
            "side": "SELL",
            "fee_rate_bps": "0",
            "transaction_hash": "0xeeefff…",
            "timestamp": "2026-06-29T17:15:57.257000Z"
          }
        }
        ```
      </CodeGroup>

      #### Tick Size Change

      <CodeGroup>
        ```python MarketTickSizeChangeEvent Type theme={null}
        class MarketTickSizeChangePayload:
            condition_id: ConditionId
            asset_id: ClobAssetId
            old_tick_size: Decimal | None
            new_tick_size: Decimal
            timestamp: datetime | None

        class MarketTickSizeChangeEvent:
            topic: Literal["market"]
            type: Literal["tick_size_change"]
            payload: MarketTickSizeChangePayload
        ```

        ```json MarketTickSizeChangeEvent Example theme={null}
        {
          "topic": "market",
          "type": "tick_size_change",
          "payload": {
            "condition_id": "0x747dc809fb79e1b05be09c42d6179459a58de2ef3e40f02484a4e1260f741f75",
            "asset_id": "107505882767731489358349912513945399560393482969656700824895970500493757150417",
            "old_tick_size": "0.01",
            "new_tick_size": "0.001",
            "timestamp": "2026-06-29T17:15:57.257000Z"
          }
        }
        ```
      </CodeGroup>
    </Accordion>

    Enable `custom_feature_enabled` to include top-of-book and market lifecycle
    updates:

    ```python theme={null}
    async with await client.subscribe(
        MarketSpec(asset_ids=[asset_id], custom_feature_enabled=True),
    ) as stream:
        async for event in stream:
            if event.type == "book":
                ...  # event: MarketBookEvent
            elif event.type == "price_change":
                ...  # event: MarketPriceChangeEvent
            elif event.type == "last_trade_price":
                ...  # event: MarketLastTradePriceEvent
            elif event.type == "tick_size_change":
                ...  # event: MarketTickSizeChangeEvent
            elif event.type == "best_bid_ask":
                ...  # event: MarketBestBidAskEvent
            elif event.type == "new_market":
                ...  # event: NewMarketEvent
            elif event.type == "market_resolved":
                ...  # event: MarketResolvedEvent
    ```

    <Accordion title="Additional Market Events">
      #### Best Bid and Ask

      <CodeGroup>
        ```python MarketBestBidAskEvent Type theme={null}
        class MarketBestBidAskPayload:
            condition_id: ConditionId
            asset_id: ClobAssetId
            best_bid: Decimal | None
            best_ask: Decimal | None
            spread: Decimal | None
            timestamp: datetime | None

        class MarketBestBidAskEvent:
            topic: Literal["market"]
            type: Literal["best_bid_ask"]
            payload: MarketBestBidAskPayload
        ```

        ```json MarketBestBidAskEvent Example theme={null}
        {
          "topic": "market",
          "type": "best_bid_ask",
          "payload": {
            "condition_id": "0x747dc809fb79e1b05be09c42d6179459a58de2ef3e40f02484a4e1260f741f75",
            "asset_id": "107505882767731489358349912513945399560393482969656700824895970500493757150417",
            "best_bid": "0.08",
            "best_ask": "0.09",
            "spread": "0.01",
            "timestamp": "2026-06-29T17:15:57.257000Z"
          }
        }
        ```
      </CodeGroup>

      #### New Market

      <CodeGroup>
        ```python NewMarketEvent Type theme={null}
        class MarketEventMessage:
            id: str
            ticker: str | None
            slug: str | None
            title: str | None
            description: str | None

        class NewMarketPayload:
            id: str
            market: str
            question: str | None
            slug: str | None
            description: str | None
            asset_ids: tuple[ClobAssetId, ...] | None
            outcomes: tuple[str, ...] | None
            event_message: MarketEventMessage | None
            timestamp: datetime | None
            tags: tuple[str, ...] | None
            condition_id: ConditionId | None
            active: bool | None
            clob_token_ids: tuple[str, ...] | None
            sports_market_type: str | None
            line: Decimal | None
            game_start_time: datetime | None
            order_price_min_tick_size: Decimal | None
            group_item_title: str | None
            taker_base_fee: Decimal | None
            fees_enabled: bool | None
            fee_schedule: object | None

        class NewMarketEvent:
            topic: Literal["market"]
            type: Literal["new_market"]
            payload: NewMarketPayload
        ```

        ```json NewMarketEvent Example theme={null}
        {
          "topic": "market",
          "type": "new_market",
          "payload": {
            "id": "123456",
            "market": "0x747dc809fb79e1b05be09c42d6179459a58de2ef3e40f02484a4e1260f741f75",
            "question": "Will the US confirm that aliens exist before 2027?",
            "slug": "will-the-us-confirm-that-aliens-exist-before-2027",
            "asset_ids": [
              "107505882767731489358349912513945399560393482969656700824895970500493757150417",
              "7305630249804085635496399869905769372294302716159034447326228509068694952392"
            ],
            "outcomes": ["Yes", "No"],
            "active": true,
            "timestamp": "2026-06-29T17:15:57.257000Z"
          }
        }
        ```
      </CodeGroup>

      #### Market Resolved

      <CodeGroup>
        ```python MarketResolvedEvent Type theme={null}
        class MarketResolvedPayload:
            id: str
            condition_id: ConditionId
            asset_ids: tuple[ClobAssetId, ...] | None
            winning_asset_id: ClobAssetId | None
            winning_outcome: str | None
            event_message: MarketEventMessage | None
            timestamp: datetime | None
            tags: tuple[str, ...] | None

        class MarketResolvedEvent:
            topic: Literal["market"]
            type: Literal["market_resolved"]
            payload: MarketResolvedPayload
        ```

        ```json MarketResolvedEvent Example theme={null}
        {
          "topic": "market",
          "type": "market_resolved",
          "payload": {
            "id": "123456",
            "condition_id": "0x747dc809fb79e1b05be09c42d6179459a58de2ef3e40f02484a4e1260f741f75",
            "asset_ids": [
              "107505882767731489358349912513945399560393482969656700824895970500493757150417",
              "7305630249804085635496399869905769372294302716159034447326228509068694952392"
            ],
            "winning_asset_id": "107505882767731489358349912513945399560393482969656700824895970500493757150417",
            "winning_outcome": "Yes",
            "timestamp": "2026-06-29T17:15:57.257000Z"
          }
        }
        ```
      </CodeGroup>
    </Accordion>
  </Tab>

  <Tab title="API">
    Connect to the market WebSocket:

    ```text theme={null}
    wss://ws-subscriptions-clob.polymarket.com/ws/market
    ```

    <Note>
      The market WebSocket uses an application-level heartbeat. Send the text frame
      `PING` every 10 seconds; the server replies with `PONG`.
    </Note>

    Once connected, send a `market` subscription frame with one or more outcome
    IDs:

    ```json theme={null}
    {
      "assets_ids": ["<asset_id>"],
      "type": "market"
    }
    ```

    <Accordion title="Standard Market Events">
      #### Order Book

      ```json theme={null}
      {
        "event_type": "book",
        "market": "0x747dc809fb79e1b05be09c42d6179459a58de2ef3e40f02484a4e1260f741f75",
        "asset_id": "107505882767731489358349912513945399560393482969656700824895970500493757150417",
        "timestamp": "1782753357257",
        "hash": "0xabc123…",
        "bids": [
          { "price": "0.08", "size": "33343.4" },
          { "price": "0.09", "size": "163939.58" }
        ],
        "asks": [
          { "price": "0.99", "size": "218442.27" },
          { "price": "0.98", "size": "13229.55" }
        ]
      }
      ```

      #### Price Change

      ```json theme={null}
      {
        "event_type": "price_change",
        "market": "0x747dc809fb79e1b05be09c42d6179459a58de2ef3e40f02484a4e1260f741f75",
        "price_changes": [
          {
            "asset_id": "107505882767731489358349912513945399560393482969656700824895970500493757150417",
            "price": "0.08",
            "size": "33343.4",
            "side": "BUY",
            "hash": "56621a121a47ed9333273e21c83b660cff37ae50",
            "best_bid": "0.08",
            "best_ask": "0.09"
          }
        ],
        "timestamp": "1782753357257"
      }
      ```

      #### Last Trade Price

      ```json theme={null}
      {
        "event_type": "last_trade_price",
        "market": "0x747dc809fb79e1b05be09c42d6179459a58de2ef3e40f02484a4e1260f741f75",
        "asset_id": "107505882767731489358349912513945399560393482969656700824895970500493757150417",
        "price": "0.08",
        "size": "219.217767",
        "fee_rate_bps": "0",
        "side": "SELL",
        "timestamp": "1782753357257",
        "transaction_hash": "0xeeefff…"
      }
      ```

      #### Tick Size Change

      ```json theme={null}
      {
        "event_type": "tick_size_change",
        "market": "0x747dc809fb79e1b05be09c42d6179459a58de2ef3e40f02484a4e1260f741f75",
        "asset_id": "107505882767731489358349912513945399560393482969656700824895970500493757150417",
        "old_tick_size": "0.01",
        "new_tick_size": "0.001",
        "timestamp": "1782753357257"
      }
      ```
    </Accordion>

    Enable `custom_feature_enabled` to include top-of-book and market lifecycle
    updates:

    ```json theme={null}
    {
      "assets_ids": ["<asset_id>"],
      "type": "market",
      "custom_feature_enabled": true
    }
    ```

    <Accordion title="Additional Market Events">
      #### Best Bid and Ask

      ```json theme={null}
      {
        "event_type": "best_bid_ask",
        "market": "0x747dc809fb79e1b05be09c42d6179459a58de2ef3e40f02484a4e1260f741f75",
        "asset_id": "107505882767731489358349912513945399560393482969656700824895970500493757150417",
        "best_bid": "0.08",
        "best_ask": "0.09",
        "spread": "0.01",
        "timestamp": "1782753357257"
      }
      ```

      #### New Market

      ```json theme={null}
      {
        "event_type": "new_market",
        "id": "123456",
        "question": "Will the US confirm that aliens exist before 2027?",
        "market": "0x747dc809fb79e1b05be09c42d6179459a58de2ef3e40f02484a4e1260f741f75",
        "slug": "will-the-us-confirm-that-aliens-exist-before-2027",
        "assets_ids": [
          "107505882767731489358349912513945399560393482969656700824895970500493757150417",
          "7305630249804085635496399869905769372294302716159034447326228509068694952392"
        ],
        "outcomes": ["Yes", "No"],
        "timestamp": "1782753357257"
      }
      ```

      #### Market Resolved

      ```json theme={null}
      {
        "event_type": "market_resolved",
        "id": "123456",
        "market": "0x747dc809fb79e1b05be09c42d6179459a58de2ef3e40f02484a4e1260f741f75",
        "assets_ids": [
          "107505882767731489358349912513945399560393482969656700824895970500493757150417",
          "7305630249804085635496399869905769372294302716159034447326228509068694952392"
        ],
        "winning_asset_id": "107505882767731489358349912513945399560393482969656700824895970500493757150417",
        "winning_outcome": "Yes",
        "timestamp": "1782753357257"
      }
      ```
    </Accordion>

    You can add or remove outcome IDs without opening a new connection:

    <CodeGroup>
      ```json Subscribe theme={null}
      {
        "assets_ids": ["<new_asset_id>"],
        "operation": "subscribe"
      }
      ```

      ```json Unsubscribe theme={null}
      {
        "assets_ids": ["<old_asset_id>"],
        "operation": "unsubscribe"
      }
      ```
    </CodeGroup>

    These frames update only the outcome set for the current market-stream
    connection.
  </Tab>
</Tabs>

## Sports Stream

Use the sports stream to keep live game information current alongside sports
markets. Updates arrive when a game goes live, its score or period changes, or
it ends. NFL and CFB updates can also reflect possession changes.

<Warning>
  Sports data is provided for informational purposes only. It may be delayed,
  contain errors, or omit recent events. Polymarket does not provide trading or
  investment advice, and this data should not be used as the basis for a trading
  decision.
</Warning>

<Tabs>
  <Tab title="TypeScript">
    Given a `PublicClient` or `SecureClient`, subscribe to the `sports` topic to receive
    every game update:

    ```ts theme={null}
    const stream = await client.subscribe([{ topic: "sports" }]);

    for await (const event of stream) {
      // event: SportsEvent
    }
    ```

    <Accordion title="Sports Event">
      <CodeGroup>
        ```ts SportsEvent Type theme={null}
        type SportsEvent = {
          topic: "sports";
          type: "sport_result";
          payload: {
            gameId: number;
            sportradarGameId?: string | null;
            slug?: string | null;
            leagueAbbreviation: string;
            homeTeam?: string | null;
            awayTeam?: string | null;
            status: string;
            live: boolean;
            ended: boolean;
            score: string;
            period?: string | null;
            elapsed?: string | null;
            finishedAt?: IsoDateTimeString | null;
            turn?: string | null;
          };
        };
        ```

        ```json SportsEvent Example theme={null}
        {
          "topic": "sports",
          "type": "sport_result",
          "payload": {
            "gameId": 5127839,
            "leagueAbbreviation": "NBA",
            "homeTeam": "Los Angeles Lakers",
            "awayTeam": "Boston Celtics",
            "status": "InProgress",
            "live": true,
            "ended": false,
            "score": "98-94",
            "period": "Q4",
            "elapsed": "05:12"
          }
        }
        ```
      </CodeGroup>

      `score` is a combined `"<home>-<away>"` string, not separate home and away
      fields.
    </Accordion>
  </Tab>

  <Tab title="Python">
    Given an `AsyncPublicClient` or `AsyncSecureClient`, subscribe with a
    `SportsSpec` to receive every game update:

    ```python theme={null}
    from polymarket.streams import SportsSpec

    async with await client.subscribe(SportsSpec()) as stream:
        async for event in stream:
            ...  # event: SportsEvent
    ```

    <Accordion title="Sports Event">
      <CodeGroup>
        ```python SportsEvent Type theme={null}
        class SportsGameResult:
            game_id: int
            sportradar_game_id: str | None
            slug: str | None
            league_abbreviation: str
            home_team: str | None
            away_team: str | None
            status: str
            live: bool
            ended: bool
            score: str
            period: str | None
            elapsed: str | None
            finished_at: datetime | None
            turn: str | None

        class SportsResultEvent:
            topic: Literal["sports"]
            type: Literal["sport_result"]
            payload: SportsGameResult

        SportsEvent = SportsResultEvent
        ```

        ```json SportsEvent Example theme={null}
        {
          "topic": "sports",
          "type": "sport_result",
          "payload": {
            "game_id": 5127839,
            "league_abbreviation": "NBA",
            "home_team": "Los Angeles Lakers",
            "away_team": "Boston Celtics",
            "status": "InProgress",
            "live": true,
            "ended": false,
            "score": "98-94",
            "period": "Q4",
            "elapsed": "05:12"
          }
        }
        ```
      </CodeGroup>

      `score` is a combined `"<home>-<away>"` string, not separate home and away
      fields.
    </Accordion>
  </Tab>

  <Tab title="API">
    Connect to the sports WebSocket:

    ```text theme={null}
    wss://sports-api.polymarket.com/ws
    ```

    <Note>
      The sports WebSocket uses an application-level heartbeat. The server sends the
      text frame `ping` every 5 seconds; reply with `pong` within 10 seconds or the
      server closes the connection.
    </Note>

    Once connected, the server starts streaming every game update. No
    subscription frame is required.

    <Accordion title="Sports Event">
      ```json theme={null}
      {
        "gameId": 5127839,
        "leagueAbbreviation": "NBA",
        "homeTeam": "Los Angeles Lakers",
        "awayTeam": "Boston Celtics",
        "status": "InProgress",
        "live": true,
        "ended": false,
        "score": "98-94",
        "period": "Q4",
        "elapsed": "05:12"
      }
      ```

      Sports messages have no envelope or event-type field. Each message is the
      game update object itself, and `score` is a combined `"<home>-<away>"`
      string.
    </Accordion>
  </Tab>
</Tabs>

### Period Values

The meaning and format of a period depend on the sport:

| Values | Meaning |
| - | - |
| `1H`, `2H` | First or second half |
| `1Q`, `2Q`, `3Q`, `4Q` | Quarter |
| `HT` | Halftime |
| `FT` | Full time in regulation |
| `FT OT` | Full time after overtime |
| `FT NR` | Full time with no result |
| `End 1`, `End 2`, … | End of an MLB inning |
| `1/3`, `2/3`, `3/3` | Map number in a best-of-three series |
| `1/5`, `2/5`, … | Map number in a best-of-five series |

### Game Status Values

Status values vary by sport and are case-sensitive:

| Sport | Values |
| - | - |
| NFL | `Scheduled`, `InProgress`, `Final`, `F/OT`, `Suspended`, `Postponed`, `Delayed`, `Canceled`, `Forfeit`, `NotNecessary` |
| NHL | `Scheduled`, `InProgress`, `Final`, `F/OT`, `F/SO`, `Suspended`, `Postponed`, `Delayed`, `Canceled`, `Forfeit`, `NotNecessary` |
| MLB | `Scheduled`, `InProgress`, `Final`, `Suspended`, `Delayed`, `Postponed`, `Canceled`, `Forfeit`, `NotNecessary` |
| NBA and CBB | `Scheduled`, `InProgress`, `Final`, `F/OT`, `Suspended`, `Postponed`, `Delayed`, `Canceled`, `Forfeit`, `NotNecessary` |
| CFB | `Scheduled`, `InProgress`, `Final`, `F/OT`, `Suspended`, `Postponed`, `Delayed`, `Canceled`, `Forfeit` |
| Soccer | `Scheduled`, `InProgress`, `Break`, `Suspended`, `PenaltyShootout`, `Final`, `Awarded`, `Postponed`, `Canceled` |
| Esports | `not_started`, `running`, `finished`, `postponed`, `canceled` |
| Tennis | `scheduled`, `inprogress`, `suspended`, `finished`, `postponed`, `cancelled` |

## Reference Prices

Stream crypto, equity, and time-weighted average reference prices through Polymarket. Authenticate, select the symbols you need, and process historical prices and live updates.

<Note>
  Reference price subscriptions require authentication.
  Existing RTDS integrations should follow the [migration
  guide](/migrate/rtds-to-polybolt).
</Note>

Use lowercase symbols. See the [PolyBolt overview](/api-reference/live-data/overview#supported-symbols) for crypto and TWAP lists, and the equity catalog below for equity symbols.

### Historical Snapshot

Each new subscription provides a snapshot of the preceding two minutes of prices and live updates. Seed local state from the snapshot, then apply the latest price. Applications that only need live prices can ignore the snapshot.

### Crypto Prices

Stream crypto reference prices in USD to keep prices current alongside related markets.

<Tabs>
  <Tab title="TypeScript">
    Call `client.subscribe` with an authenticated `SecureClient` from `@polymarket/client` 0.11.0 or later. See [Wallet Integrations](/getting-started/typescript#wallet-integrations) to create the client.

    ```ts theme={null}
    const stream = await client.subscribe([
      { topic: "prices.crypto", symbols: ["btcusd", "ethusd"] },
    ]);

    try {
      for await (const event of stream) {
        // event: CryptoPriceEvent
        if (event.type === "subscribe") {
          const history = event.payload.data;
          // Seed local state from the snapshot.
        } else {
          const price = event.payload.value;
          const observedAt = event.payload.timestamp;
          // Apply the latest price.
        }
      }
    } finally {
      await stream.close();
    }
    ```

    <Accordion title="Output: CryptoPriceEvent">
      **events: CryptoPriceEvent\[]**

      <CodeGroup>
        ```ts CryptoPriceEvent Union theme={null}
        type CryptoPriceEvent =
          | {
              topic: "prices.crypto";
              type: "subscribe";
              timestamp: EpochMilliseconds;
              seq?: number;
              dropped?: number;
              payload: {
                symbol: string;
                data: { timestamp: EpochMilliseconds; value: DecimalString }[];
              };
            }
          | {
              topic: "prices.crypto";
              type: "update";
              timestamp: EpochMilliseconds;
              seq?: number;
              dropped?: number;
              payload: {
                symbol: string;
                timestamp: EpochMilliseconds;
                value: DecimalString;
                receivedAt: EpochMilliseconds | undefined;
                isCarriedForward: boolean | undefined;
              };
            };
        ```

        ```json CryptoPriceEvent Example theme={null}
        [
          {
            "topic": "prices.crypto",
            "type": "subscribe",
            "timestamp": 1788886176000,
            "seq": 1,
            "payload": {
              "symbol": "btcusd",
              "data": [
                {
                  "timestamp": 1788886057000,
                  "value": "78803.76173179"
                },
                {
                  "timestamp": 1788886058000,
                  "value": "78801.86287741"
                },
                {
                  "timestamp": 1788886059000,
                  "value": "78798.28703224"
                }
              ]
            }
          },
          {
            "topic": "prices.crypto",
            "type": "update",
            "timestamp": 1788886177000,
            "seq": 5,
            "payload": {
              "symbol": "btcusd",
              "timestamp": 1788886177000,
              "value": "78794.15450441"
            }
          }
        ]
        ```
      </CodeGroup>
    </Accordion>

    For live prices only, skip events whose `type` is `"subscribe"`.
  </Tab>

  <Tab title="Python">
    Call `client.subscribe` with an authenticated `AsyncSecureClient` from `polymarket-client` 0.11.0 or later. Complete [Secure Client setup](/getting-started/python#secure-client) first, and run this example inside an async function.

    ```python theme={null}
    from polymarket.streams import CryptoPriceSpec

    async with await client.subscribe(
        CryptoPriceSpec(symbols=["btcusd", "ethusd"])
    ) as stream:
        async for event in stream:
            # event: CryptoPriceEvent
            if event.type == "subscribe":
                history = event.payload.data
                # Seed local state from the snapshot.
            else:
                price = event.payload.value
                observed_at = event.payload.timestamp
                # Apply the latest price.
    ```

    <Accordion title="Output: CryptoPriceEvent">
      **event: CryptoPriceEvent**

      <CodeGroup>
        ```python CryptoPriceEvent Union theme={null}
        class RealtimePricePoint:
            timestamp: datetime
            value: Decimal

        class RealtimePriceSnapshot:
            symbol: str
            data: tuple[RealtimePricePoint, ...]

        class RealtimePriceUpdate:
            symbol: str
            timestamp: datetime
            value: Decimal
            received_at: datetime | None
            is_carried_forward: bool | None

        class CryptoPriceSnapshotEvent:
            topic: Literal["prices.crypto"]
            type: Literal["subscribe"]
            timestamp: datetime
            seq: int | None
            dropped: int | None
            payload: RealtimePriceSnapshot

        class CryptoPriceUpdateEvent:
            topic: Literal["prices.crypto"]
            type: Literal["update"]
            timestamp: datetime
            seq: int | None
            dropped: int | None
            payload: RealtimePriceUpdate

        CryptoPriceEvent = CryptoPriceSnapshotEvent | CryptoPriceUpdateEvent
        ```

        ```json CryptoPriceEvent Example theme={null}
        {
          "timestamp": "2026-09-08T16:49:37Z",
          "seq": 5,
          "topic": "prices.crypto",
          "type": "update",
          "payload": {
            "timestamp": "2026-09-08T16:49:37Z",
            "value": "78794.15450441",
            "symbol": "btcusd"
          }
        }
        ```
      </CodeGroup>
    </Accordion>

    Values are `Decimal`, and timestamps are UTC `datetime` objects.

    For live prices only, skip events whose `type` is `"subscribe"`.
  </Tab>

  <Tab title="API">
    Connect to PolyBolt and authenticate before subscribing to crypto prices.

    <Steps>
      <Step title="Connect">
        Open a WebSocket connection to:

        ```text theme={null}
        wss://ws-live-v2.polymarket.com/ws
        ```
      </Step>

      <Step title="Authenticate">
        Send your [CLOB API credentials](/getting-started/api#authentication) on the open connection:

        ```json theme={null}
        {
          "op": "auth",
          "rid": "a1",
          "auth": {
            "apiKey": "<api key>",
            "secret": "<api secret>",
            "passphrase": "<api passphrase>"
          }
        }
        ```
      </Step>

      <Step title="Wait for Authentication">
        Wait for the server to confirm authentication before sending a subscription:

        ```json theme={null}
        {
          "op": "authed",
          "rid": "a1"
        }
        ```
      </Step>

      <Step title="Subscribe to Crypto Prices">
        Send this frame on the authenticated connection to subscribe to BTC/USD:

        ```json theme={null}
        {
          "op": "subscribe",
          "rid": "s1",
          "subscriptions": [
            {
              "channel": "price.crypto",
              "filter": {
                "symbol": "btcusd"
              }
            }
          ]
        }
        ```
      </Step>
    </Steps>
  </Tab>
</Tabs>

### Equity Prices

Stream reference prices for stocks, ETFs, forex pairs, precious metals, and commodities.

<Tabs>
  <Tab title="TypeScript">
    Call `client.subscribe` to subscribe to the `prices.equity` topic and your chosen symbols with an authenticated `SecureClient`.

    ```ts theme={null}
    const stream = await client.subscribe([
      { topic: "prices.equity", symbol: "aapl" },
    ]);

    try {
      for await (const event of stream) {
        // event: EquityPriceEvent
        if (event.type === "subscribe") {
          const history = event.payload.data;
          // Seed local state from the snapshot.
        } else {
          const price = event.payload.value;
          const observedAt = event.payload.timestamp;
          // Apply the latest price.
        }
      }
    } finally {
      await stream.close();
    }
    ```

    <Accordion title="Output: EquityPriceEvent">
      **events: EquityPriceEvent\[]**

      <CodeGroup>
        ```ts EquityPriceEvent Union theme={null}
        type EquityPriceEvent =
          | {
              topic: "prices.equity";
              type: "subscribe";
              timestamp: EpochMilliseconds;
              seq?: number;
              dropped?: number;
              payload: {
                symbol: string;
                data: { timestamp: EpochMilliseconds; value: DecimalString }[];
              };
            }
          | {
              topic: "prices.equity";
              type: "update";
              timestamp: EpochMilliseconds;
              seq?: number;
              dropped?: number;
              payload: {
                symbol: string;
                timestamp: EpochMilliseconds;
                value: DecimalString;
                receivedAt: EpochMilliseconds | undefined;
                isCarriedForward: boolean | undefined;
              };
            };
        ```

        ```json EquityPriceEvent Example theme={null}
        [
          {
            "topic": "prices.equity",
            "type": "subscribe",
            "timestamp": 1788886176400,
            "seq": 1,
            "payload": {
              "symbol": "aapl",
              "data": [
                {
                  "timestamp": 1788886056800,
                  "value": "316.11"
                },
                {
                  "timestamp": 1788886057000,
                  "value": "316.11"
                },
                {
                  "timestamp": 1788886057200,
                  "value": "316.11001"
                }
              ]
            }
          },
          {
            "topic": "prices.equity",
            "type": "update",
            "timestamp": 1788886176600,
            "seq": 2,
            "payload": {
              "symbol": "aapl",
              "timestamp": 1788886176600,
              "value": "316.1",
              "receivedAt": 1788886176600
            }
          }
        ]
        ```
      </CodeGroup>
    </Accordion>

    For live prices only, skip events whose `type` is `"subscribe"`.
  </Tab>

  <Tab title="Python">
    Call `client.subscribe` to subscribe to the `prices.equity` topic and your chosen symbols with an authenticated `AsyncSecureClient`.

    ```python theme={null}
    from polymarket.streams import EquityPriceSpec

    async with await client.subscribe(
        EquityPriceSpec(symbol="aapl")
    ) as stream:
        async for event in stream:
            # event: EquityPriceEvent
            if event.type == "subscribe":
                history = event.payload.data
                # Seed local state from the snapshot.
            else:
                price = event.payload.value
                observed_at = event.payload.timestamp
                # Apply the latest price.
    ```

    <Accordion title="Output: EquityPriceEvent">
      **event: EquityPriceEvent**

      <CodeGroup>
        ```python EquityPriceEvent Union theme={null}
        class RealtimePricePoint:
            timestamp: datetime
            value: Decimal

        class RealtimePriceSnapshot:
            symbol: str
            data: tuple[RealtimePricePoint, ...]

        class RealtimePriceUpdate:
            symbol: str
            timestamp: datetime
            value: Decimal
            received_at: datetime | None
            is_carried_forward: bool | None

        class EquityPriceSnapshotEvent:
            topic: Literal["prices.equity"]
            type: Literal["subscribe"]
            timestamp: datetime
            seq: int | None
            dropped: int | None
            payload: RealtimePriceSnapshot

        class EquityPriceUpdateEvent:
            topic: Literal["prices.equity"]
            type: Literal["update"]
            timestamp: datetime
            seq: int | None
            dropped: int | None
            payload: RealtimePriceUpdate

        EquityPriceEvent = EquityPriceSnapshotEvent | EquityPriceUpdateEvent
        ```

        ```json EquityPriceEvent Example theme={null}
        {
          "timestamp": "2026-09-08T16:49:36.600000Z",
          "seq": 2,
          "topic": "prices.equity",
          "type": "update",
          "payload": {
            "timestamp": "2026-09-08T16:49:36.600000Z",
            "value": "316.1",
            "symbol": "aapl",
            "received_at": "2026-09-08T16:49:36.600000Z"
          }
        }
        ```
      </CodeGroup>
    </Accordion>

    Values are `Decimal`, and timestamps are UTC `datetime` objects.

    For live updates only, set `types=["update"]`. Omit `types` or pass an empty list to receive history and updates. Updates may include `received_at` and `is_carried_forward`.
  </Tab>

  <Tab title="API">
    Reuse the authenticated connection from the [Crypto Prices](#crypto-prices) API example and send this frame to subscribe to AAPL:

    ```json theme={null}
    {
      "op": "subscribe",
      "rid": "s2",
      "subscriptions": [
        {
          "channel": "price.equity",
          "filter": {
            "symbol": "aapl"
          }
        }
      ]
    }
    ```
  </Tab>
</Tabs>

#### Supported Equity Symbols

| Asset class | Supported symbols |
| - | - |
| Stocks | `aapl`, `tsla`, `msft`, `googl`, `amzn`, `meta`, `nvda`, `nflx`, `pltr`, `open`, `rklb`, `abnb`, `coin`, `hood` |
| ETFs | `qqq`, `spy`, `ewy`, `vxx` |
| Forex | `eurusd`, `gbpusd`, `usdcad`, `usdjpy`, `usdkrw` |
| Precious metals | `xauusd`, `xagusd` |
| Commodities | `wti`, `cc`, `ngd` |

#### Market Hours

When the market for an asset is closed, the stream continues with its last
known price and marks that value as carried forward. During market hours,
prices can update up to five times per second for each feed.

### TWAP Prices

A time-weighted average price (TWAP) represents an asset's price across a lookback window. Stream Chainlink-computed crypto TWAPs with a fixed 60-second window through Polymarket.

<Tabs>
  <Tab title="TypeScript">
    Call `client.subscribe` to subscribe to the `prices.crypto.twap` topic and your chosen symbols with an authenticated `SecureClient`.

    ```ts theme={null}
    const stream = await client.subscribe([
      { topic: "prices.crypto.twap", symbols: ["btcusd"] },
    ]);

    try {
      for await (const event of stream) {
        // event: CryptoTwapPriceEvent
        if (event.type === "subscribe") {
          const history = event.payload.data;
          // Seed local state from the snapshot.
        } else {
          const price = event.payload.value;
          const observedAt = event.payload.timestamp;
          // Apply the latest price.
        }
      }
    } finally {
      await stream.close();
    }
    ```

    <Accordion title="Output: CryptoTwapPriceEvent">
      **events: CryptoTwapPriceEvent\[]**

      <CodeGroup>
        ```ts CryptoTwapPriceEvent Union theme={null}
        type CryptoTwapPriceEvent =
          | {
              topic: "prices.crypto.twap";
              type: "subscribe";
              timestamp: EpochMilliseconds;
              seq?: number;
              dropped?: number;
              payload: {
                symbol: string;
                data: { timestamp: EpochMilliseconds; value: DecimalString }[];
                windowSeconds: 60;
              };
            }
          | {
              topic: "prices.crypto.twap";
              type: "update";
              timestamp: EpochMilliseconds;
              seq?: number;
              dropped?: number;
              payload: {
                symbol: string;
                timestamp: EpochMilliseconds;
                value: DecimalString;
                windowSeconds: 60;
              };
            };
        ```

        ```json CryptoTwapPriceEvent Example theme={null}
        [
          {
            "topic": "prices.crypto.twap",
            "type": "subscribe",
            "timestamp": 1788886175000,
            "seq": 2,
            "payload": {
              "symbol": "btcusd",
              "data": [
                {
                  "timestamp": 1788886057000,
                  "value": "78788.525642908795142144"
                },
                {
                  "timestamp": 1788886058000,
                  "value": "78788.786579938813673472"
                },
                {
                  "timestamp": 1788886059000,
                  "value": "78789.052518750893375488"
                }
              ],
              "windowSeconds": 60
            }
          },
          {
            "topic": "prices.crypto.twap",
            "type": "update",
            "timestamp": 1788886177000,
            "seq": 3,
            "payload": {
              "symbol": "btcusd",
              "timestamp": 1788886177000,
              "value": "78803.715261094101516288",
              "windowSeconds": 60
            }
          }
        ]
        ```
      </CodeGroup>
    </Accordion>

    For live prices only, skip events whose `type` is `"subscribe"`. `payload.value` is already an exact decimal string. No E18 conversion is needed.

    Use a canonical symbol such as `btcusd`. The returned `windowSeconds: 60` describes the lookback period, not the update interval. Use `payload.timestamp` to check price freshness.
  </Tab>

  <Tab title="Python">
    Call `client.subscribe` to subscribe to the `prices.crypto.twap` topic and your chosen symbols with an authenticated `AsyncSecureClient`.

    ```python theme={null}
    from polymarket.streams import CryptoTwapPriceSpec

    async with await client.subscribe(
        CryptoTwapPriceSpec(symbols=["btcusd"])
    ) as stream:
        async for event in stream:
            # event: CryptoTwapPriceEvent
            if event.type == "subscribe":
                history = event.payload.data
                # Seed local state from the snapshot.
            else:
                price = event.payload.value
                observed_at = event.payload.timestamp
                # Apply the latest price.
    ```

    <Accordion title="Output: CryptoTwapPriceEvent">
      **event: CryptoTwapPriceEvent**

      <CodeGroup>
        ```python CryptoTwapPriceEvent Union theme={null}
        class RealtimePricePoint:
            timestamp: datetime
            value: Decimal

        class RealtimeTwapSnapshot:
            symbol: str
            data: tuple[RealtimePricePoint, ...]
            window_seconds: Literal[60]

        class RealtimeTwapUpdate:
            symbol: str
            timestamp: datetime
            value: Decimal
            window_seconds: Literal[60]

        class CryptoTwapPriceSnapshotEvent:
            topic: Literal["prices.crypto.twap"]
            type: Literal["subscribe"]
            timestamp: datetime
            seq: int | None
            dropped: int | None
            payload: RealtimeTwapSnapshot

        class CryptoTwapPriceUpdateEvent:
            topic: Literal["prices.crypto.twap"]
            type: Literal["update"]
            timestamp: datetime
            seq: int | None
            dropped: int | None
            payload: RealtimeTwapUpdate

        CryptoTwapPriceEvent = CryptoTwapPriceSnapshotEvent | CryptoTwapPriceUpdateEvent
        ```

        ```json CryptoTwapPriceEvent Example theme={null}
        {
          "timestamp": "2026-09-08T16:49:37Z",
          "seq": 3,
          "topic": "prices.crypto.twap",
          "type": "update",
          "payload": {
            "timestamp": "2026-09-08T16:49:37Z",
            "value": "78803.715261094101516288",
            "symbol": "btcusd",
            "window_seconds": 60
          }
        }
        ```
      </CodeGroup>
    </Accordion>

    Values are `Decimal`, and timestamps are UTC `datetime` objects.

    `payload.window_seconds` is always `60` and describes the lookback window. Use `payload.value` directly without E18 scaling, and use `payload.timestamp` to check freshness.
  </Tab>

  <Tab title="API">
    Reuse the authenticated connection from the [Crypto Prices](#crypto-prices) API example and send this frame to subscribe to the 60-second BTC/USD TWAP:

    ```json theme={null}
    {
      "op": "subscribe",
      "rid": "s3",
      "subscriptions": [
        {
          "channel": "price.crypto.twap",
          "filter": {
            "symbol": "btcusd",
            "window_seconds": 60
          }
        }
      ]
    }
    ```
  </Tab>
</Tabs>

## Comments

<Warning>
  Live comment and reaction streaming is being retired without a replacement
  streaming channel. Check below for the corresponding fetch method.
</Warning>

<Tabs>
  <Tab title="TypeScript">
    Create a public client and call `client.listComments()` to list comments for an event. This method does not provide live comment or reaction events.

    ```ts theme={null}
    import {
      CommentParentEntityType,
      createPublicClient,
    } from "@polymarket/client";

    const client = createPublicClient();
    const pages = client.listComments({
      parentEntityId: "18396",
      parentEntityType: CommentParentEntityType.Event,
      pageSize: 20,
      order: "id",
      ascending: true,
    });
    const page = await pages.firstPage();

    console.log(page.items);
    ```

    `page.items` contains `Comment` objects. Check `page.hasMore` for more results and continue with `pages.from(page.nextCursor)`.

    <Accordion title="Output: Comment">
      One comment from `page.items`, serialized as JSON with selected fields shown.

      ```json theme={null}
      {
        "id": "1020073",
        "body": "@truce @yayyo",
        "parentEntityType": "Event",
        "parentEntityID": "18396",
        "createdAt": "2025-02-12T00:48:05.40822Z",
        "reactionCount": 2
      }
      ```
    </Accordion>
  </Tab>

  <Tab title="Python">
    Create a public client and call `client.list_comments()` to list comments for an event. This method does not provide live comment or reaction events.

    ```python theme={null}
    from polymarket import AsyncPublicClient

    async with AsyncPublicClient() as client:
        pages = client.list_comments(
            parent_entity_id="18396",
            parent_entity_type="Event",
            page_size=20,
            order="id",
            ascending=True,
        )
        page = await pages.first_page()

        print(page.items)
    ```

    `page.items` contains `Comment` objects. Check `page.has_more` for more results and continue with `pages.from_cursor(page.next_cursor)`.

    <Accordion title="Output: Comment">
      One comment from `page.items`, serialized as JSON with selected fields shown.

      ```json theme={null}
      {
        "id": "1020073",
        "body": "@truce @yayyo",
        "parent_entity_type": "Event",
        "parent_entity_id": "18396",
        "created_at": "2025-02-12T00:48:05.408220Z",
        "reaction_count": 2
      }
      ```
    </Accordion>
  </Tab>

  <Tab title="API">
    Use `GET /comments` on the Gamma API to list comments for an event. This request does not provide live comment or reaction events.

    ```bash theme={null}
    curl --get "https://gamma-api.polymarket.com/comments" \
      --data-urlencode "parent_entity_id=18396" \
      --data-urlencode "parent_entity_type=Event" \
      --data-urlencode "limit=20" \
      --data-urlencode "offset=0" \
      --data-urlencode "order=id" \
      --data-urlencode "ascending=true"
    ```

    The response is an array of comments.

    <Accordion title="Output: Comment[]">
      First comment in the response, with selected fields shown.

      ```json theme={null}
      [
        {
          "id": "1020073",
          "body": "@truce @yayyo",
          "parentEntityType": "Event",
          "parentEntityID": 18396,
          "createdAt": "2025-02-12T00:48:05.40822Z",
          "reactionCount": 2
        }
      ]
      ```
    </Accordion>
  </Tab>
</Tabs>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.