Skip to main content
Room ID: polymarket_markets_stream
Endpoint: wss://api.struct.to/ws
Rate: 0.025 credits per message
Low-latency push feed of market rows — same shape GET /polymarket/market returns, including per-outcome price with latest_block + latest_confirmed_at watermarks. The server maintains an in-memory cache of open markets only, refreshed via a slow full poll plus a fast 500ms newest-first poll, and merged live from the prediction_condition_metrics and prediction_trades Kafka streams with per-timeframe block/timestamp ordering. No initial snapshot is pushed on subscribe. Clients seed from GET /polymarket/market and then apply deltas from this stream.
Related guides: Building a live trending feed seeds from the markets list and stays warm via this stream, and Ranking markets by CLOB rewards tracks live reward changes through it.

Subscription model

Each client has up to 8 active slots per room (4 cadences × 2 modes). Re-subscribing to the same (interval_ms, mode) pair replaces the previous subscription. Unsubscribe one slot with action: "unsubscribe" plus interval_ms and mode, or clear everything with action: "unsubscribe_all".
  • Cadence (interval_ms): 500, 1000, 3000, or 10000.
  • Filter mode: same validation as the REST list endpoint (timeframe, search length, list caps). search is a case-insensitive substring match on title. No sort / limit — you get every matching row that changed.
  • Ids mode: any combination of condition_ids, market_slugs, and event_slugs (matches all child markets of those events). Max 500 ids total per subscription.
Updates fire only when a cache row is dirtied by (a) a fresh Kafka metric snapshot with latest_block >= cached, (b) a confirmed trade with block >= cached, (c) a slow-poll field diff, or (d) the fast newest-first poll discovering a brand-new market. Quiet markets produce zero messages. Each outcome in outcomes[] carries latest_block and latest_confirmed_at (Unix seconds) — the block/ts of the most recent price write from prediction_position_metrics. Consumers can use these to reject out-of-order price merges locally.

Subscribe

Message fields

Filter fields (mode=filter)

Supports the same filters as the REST markets list: search, categories, exclude_categories, tags, exclude_tags, min_volume / max_volume, min_txns / max_txns, min_unique_traders / max_unique_traders, min_liquidity / max_liquidity, min_holders / max_holders, start_time / end_time, has_rewards, and timeframe (1m, 5m, 30m, 1h, 6h, 24h, 7d, 30d). status is not accepted — the cache only holds open markets.

Example — filter mode

Example — ids mode

Unsubscribe one slot

Response

Events

markets_stream_update

Server-pushed event fired only for rows that changed AND matched this subscription since the last flush tick. data contains full market rows — not deltas — so clients should merge by condition_id. Each outcome in data[i].outcomes carries latest_block + latest_confirmed_at price-update watermarks.

Envelope

MarketResponse

MarketOutcome

SimpleTimeframeMetrics

ClobReward

Example

Last modified on June 16, 2026