Skip to main content

0007. Every displayed price comes from the market feed

  • Status: Accepted
  • Date: 2026-09-30

Context

Polymarket exposes current prices in several places: the Market WebSocket (books, trades, best bid and ask), CLOB REST (/book, /price, /midpoint, /spread), and Gamma listings (outcomePrices, best bid and ask, last trade price) that arrive with event and market metadata. Using Gamma prices for lists and the Market WS for the market view would show two different prices for the same outcome on two screens. Gamma prices are also cached on the venue side and in our market_cache. When the Market WS goes stale, a list priced from Gamma still looks live, which hides the outage. CLAUDE.md allows one source per signal and no fallbacks, and a clicked price becomes a limit order at exactly that price, so the displayed price must be the book the backend holds.

Decision

  • Every price shown anywhere (board, lists, watchlist, market view, ladder) comes from a book:<token_id> WebSocket topic, which engine/books produces from the venue market feed.
  • Values derived from a price, such as spread or midpoint, are derived from the same book.
  • REST responses carry no current prices. Search results, event listings, event and market detail, the board and the watchlist return metadata only. The Phase 1 contract has no price field on them.
  • Gamma outcomePrices and other Gamma price fields are never shown.
  • CLOB REST price endpoints are not used for display, and a book is never rebuilt from REST /book: a resync resubscribes the token on the market feed for a fresh book.
  • A list subscribes to the book topics of its visible rows and unsubscribes when rows leave the view. A socket holds at most 500 topics.
  • Price history for charts is a separate signal with its own source (CLOB prices-history, PLAN §3.7). It shows past prices, not the current one.

Consequences

  • The same outcome shows the same price on every screen, and it is the price a click sends.
  • When the market feed is stale, every price greys out together. Nothing looks live that is not.
  • A row shows no price until its book snapshot arrives. The first view of a market that no one was watching has a short blank.
  • Scrolling a long list subscribes and unsubscribes book topics. The hub and engine/books must handle that churn, and the venue feed watches more tokens. The venue’s per-connection token limits are not documented (polymarket.md §8).
  • A market with no live book shows no price.
  • Volume and liquidity are metadata from Gamma, not prices. Tick size and minimum size keep their own row in the PLAN §3.7 table: CLOB market info at subscribe, then the market feed’s tick_size_change.

Alternatives considered

  • Show Gamma prices in lists, WS prices in the market view. Rejected. Two sources for one signal; lists would look live while the feed is down.
  • Poll CLOB /prices in batches for lists. Rejected. A second source, polling, and rate-limit cost that grows with the list.
  • Gamma or REST prices as a fallback when the feed is down. Rejected. A fallback hides the outage that the stale state is meant to show.