Market Stream
Use the market stream to keep your application in sync with changes to a market’s order book and trading state.- TypeScript
- Python
- API
Given a
Enable
PublicClient or SecureClient, subscribe to the market topic with one or
more token IDs:const tokenId = "<token_id>";
const stream = await client.subscribe([
{
topic: "market",
tokenIds: [tokenId],
},
]);
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;
}
}
Standard Market Events
Standard Market Events
Order Book
type OrderBookLevel = {
price: DecimalString;
size: DecimalString;
};
type MarketBookEvent = {
topic: "market";
type: "book";
payload: {
market: string;
tokenId: TokenId;
bids: OrderBookLevel[];
asks: OrderBookLevel[];
hash?: string | null;
timestamp?: string | null;
minOrderSize?: DecimalString | null;
tickSize?: DecimalString | null;
negRisk?: boolean | null;
lastTradePrice?: DecimalString | null;
};
};
{
"topic": "market",
"type": "book",
"payload": {
"market": "0x747dc809fb79e1b05be09c42d6179459a58de2ef3e40f02484a4e1260f741f75",
"tokenId": "107505882767731489358349912513945399560393482969656700824895970500493757150417",
"bids": [{ "price": "0.08", "size": "33343.4" }],
"asks": [{ "price": "0.09", "size": "163939.58" }],
"hash": "0xabc123…",
"timestamp": "1782753357257"
}
}
Price Change
type PriceChange = {
tokenId: TokenId;
price: DecimalString;
size: DecimalString;
side: OrderSide;
hash?: string | null;
bestBid?: DecimalString | null;
bestAsk?: DecimalString | null;
};
type MarketPriceChangeEvent = {
topic: "market";
type: "price_change";
payload: {
market: string;
priceChanges: PriceChange[];
timestamp?: string | null;
};
};
{
"topic": "market",
"type": "price_change",
"payload": {
"market": "0x747dc809fb79e1b05be09c42d6179459a58de2ef3e40f02484a4e1260f741f75",
"priceChanges": [
{
"tokenId": "107505882767731489358349912513945399560393482969656700824895970500493757150417",
"price": "0.08",
"size": "33343.4",
"side": "BUY",
"hash": "56621a121a47ed9333273e21c83b660cff37ae50",
"bestBid": "0.08",
"bestAsk": "0.09"
}
],
"timestamp": "1782753357257"
}
}
Last Trade Price
type MarketLastTradePriceEvent = {
topic: "market";
type: "last_trade_price";
payload: {
market: string;
tokenId: TokenId;
price: DecimalString;
size?: DecimalString | null;
feeRateBps?: DecimalString | null;
side: OrderSide;
timestamp?: string | null;
transactionHash?: string | null;
};
};
{
"topic": "market",
"type": "last_trade_price",
"payload": {
"market": "0x747dc809fb79e1b05be09c42d6179459a58de2ef3e40f02484a4e1260f741f75",
"tokenId": "107505882767731489358349912513945399560393482969656700824895970500493757150417",
"price": "0.08",
"size": "219.217767",
"feeRateBps": "0",
"side": "SELL",
"timestamp": "1782753357257",
"transactionHash": "0xeeefff…"
}
}
Tick Size Change
type MarketTickSizeChangeEvent = {
topic: "market";
type: "tick_size_change";
payload: {
market: string;
tokenId: TokenId;
oldTickSize?: DecimalString | null;
newTickSize: DecimalString;
timestamp?: string | null;
};
};
{
"topic": "market",
"type": "tick_size_change",
"payload": {
"market": "0x747dc809fb79e1b05be09c42d6179459a58de2ef3e40f02484a4e1260f741f75",
"tokenId": "107505882767731489358349912513945399560393482969656700824895970500493757150417",
"oldTickSize": "0.01",
"newTickSize": "0.001",
"timestamp": "1782753357257"
}
}
customFeatureEnabled to include top-of-book and market lifecycle
updates:const stream = await client.subscribe([
{
topic: "market",
tokenIds: [tokenId],
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;
}
}
Additional Market Events
Additional Market Events
Best Bid and Ask
type MarketBestBidAskEvent = {
topic: "market";
type: "best_bid_ask";
payload: {
market: string;
tokenId: TokenId;
bestBid?: DecimalString | null;
bestAsk?: DecimalString | null;
spread?: DecimalString | null;
timestamp?: string | null;
};
};
{
"topic": "market",
"type": "best_bid_ask",
"payload": {
"market": "0x747dc809fb79e1b05be09c42d6179459a58de2ef3e40f02484a4e1260f741f75",
"tokenId": "107505882767731489358349912513945399560393482969656700824895970500493757150417",
"bestBid": "0.08",
"bestAsk": "0.09",
"spread": "0.01",
"timestamp": "1782753357257"
}
}
New Market
type NewMarketEvent = {
topic: "market";
type: "new_market";
payload: {
id: string;
question?: string | null;
market: string;
slug?: string | null;
description?: string | null;
tokenIds?: TokenId[] | 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?: CtfConditionId | 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;
};
};
{
"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",
"tokenIds": [
"107505882767731489358349912513945399560393482969656700824895970500493757150417",
"7305630249804085635496399869905769372294302716159034447326228509068694952392"
],
"outcomes": ["Yes", "No"],
"active": true,
"timestamp": "1782753357257"
}
}
Market Resolved
type MarketResolvedEvent = {
topic: "market";
type: "market_resolved";
payload: {
id: string;
market: string;
tokenIds?: TokenId[] | null;
winningTokenId?: TokenId | 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;
};
};
{
"topic": "market",
"type": "market_resolved",
"payload": {
"id": "123456",
"market": "0x747dc809fb79e1b05be09c42d6179459a58de2ef3e40f02484a4e1260f741f75",
"tokenIds": [
"107505882767731489358349912513945399560393482969656700824895970500493757150417",
"7305630249804085635496399869905769372294302716159034447326228509068694952392"
],
"winningTokenId": "107505882767731489358349912513945399560393482969656700824895970500493757150417",
"winningOutcome": "Yes",
"timestamp": "1782753357257"
}
}
Given an
Enable
AsyncPublicClient or AsyncSecureClient, subscribe to the market
stream with a MarketSpec containing one or more token IDs:from polymarket.streams import MarketSpec
token_id = "<token_id>"
async with await client.subscribe(
MarketSpec(token_ids=[token_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
Standard Market Events
Standard Market Events
Order Book
class OrderBookLevel:
price: Decimal
size: Decimal
class MarketBookPayload:
market: str
token_id: TokenId
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
{
"topic": "market",
"type": "book",
"payload": {
"market": "0x747dc809fb79e1b05be09c42d6179459a58de2ef3e40f02484a4e1260f741f75",
"token_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"
}
}
Price Change
class PriceChange:
token_id: TokenId
price: Decimal
size: Decimal
side: Literal["BUY", "SELL"]
hash: str | None
best_bid: Decimal | None
best_ask: Decimal | None
class MarketPriceChangePayload:
market: str
price_changes: tuple[PriceChange, ...]
timestamp: datetime | None
class MarketPriceChangeEvent:
topic: Literal["market"]
type: Literal["price_change"]
payload: MarketPriceChangePayload
{
"topic": "market",
"type": "price_change",
"payload": {
"market": "0x747dc809fb79e1b05be09c42d6179459a58de2ef3e40f02484a4e1260f741f75",
"price_changes": [
{
"token_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"
}
}
Last Trade Price
class MarketLastTradePricePayload:
market: str
token_id: TokenId
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
{
"topic": "market",
"type": "last_trade_price",
"payload": {
"market": "0x747dc809fb79e1b05be09c42d6179459a58de2ef3e40f02484a4e1260f741f75",
"token_id": "107505882767731489358349912513945399560393482969656700824895970500493757150417",
"price": "0.08",
"size": "219.217767",
"side": "SELL",
"fee_rate_bps": "0",
"transaction_hash": "0xeeefff…",
"timestamp": "2026-06-29T17:15:57.257000Z"
}
}
Tick Size Change
class MarketTickSizeChangePayload:
market: str
token_id: TokenId
old_tick_size: Decimal | None
new_tick_size: Decimal
timestamp: datetime | None
class MarketTickSizeChangeEvent:
topic: Literal["market"]
type: Literal["tick_size_change"]
payload: MarketTickSizeChangePayload
{
"topic": "market",
"type": "tick_size_change",
"payload": {
"market": "0x747dc809fb79e1b05be09c42d6179459a58de2ef3e40f02484a4e1260f741f75",
"token_id": "107505882767731489358349912513945399560393482969656700824895970500493757150417",
"old_tick_size": "0.01",
"new_tick_size": "0.001",
"timestamp": "2026-06-29T17:15:57.257000Z"
}
}
custom_feature_enabled to include top-of-book and market lifecycle
updates:async with await client.subscribe(
MarketSpec(token_ids=[token_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
Additional Market Events
Additional Market Events
Best Bid and Ask
class MarketBestBidAskPayload:
market: str
token_id: TokenId
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
{
"topic": "market",
"type": "best_bid_ask",
"payload": {
"market": "0x747dc809fb79e1b05be09c42d6179459a58de2ef3e40f02484a4e1260f741f75",
"token_id": "107505882767731489358349912513945399560393482969656700824895970500493757150417",
"best_bid": "0.08",
"best_ask": "0.09",
"spread": "0.01",
"timestamp": "2026-06-29T17:15:57.257000Z"
}
}
New Market
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
token_ids: tuple[TokenId, ...] | None
outcomes: tuple[str, ...] | None
event_message: MarketEventMessage | None
timestamp: datetime | None
tags: tuple[str, ...] | None
condition_id: CtfConditionId | 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
{
"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",
"token_ids": [
"107505882767731489358349912513945399560393482969656700824895970500493757150417",
"7305630249804085635496399869905769372294302716159034447326228509068694952392"
],
"outcomes": ["Yes", "No"],
"active": true,
"timestamp": "2026-06-29T17:15:57.257000Z"
}
}
Market Resolved
class MarketResolvedPayload:
id: str
market: str
token_ids: tuple[TokenId, ...] | None
winning_token_id: TokenId | 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
{
"topic": "market",
"type": "market_resolved",
"payload": {
"id": "123456",
"market": "0x747dc809fb79e1b05be09c42d6179459a58de2ef3e40f02484a4e1260f741f75",
"token_ids": [
"107505882767731489358349912513945399560393482969656700824895970500493757150417",
"7305630249804085635496399869905769372294302716159034447326228509068694952392"
],
"winning_token_id": "107505882767731489358349912513945399560393482969656700824895970500493757150417",
"winning_outcome": "Yes",
"timestamp": "2026-06-29T17:15:57.257000Z"
}
}
Connect to the market WebSocket:Once connected, send a
Enable
You can add or remove token IDs without opening a new connection:These frames update only the token set for the current market-stream
connection.
wss://ws-subscriptions-clob.polymarket.com/ws/market
The market WebSocket uses an application-level heartbeat. Send the text frame
PING every 10 seconds; the server replies with PONG.market subscription frame with one or more token
IDs:{
"assets_ids": ["<token_id>"],
"type": "market"
}
Standard Market Events
Standard Market Events
Order Book
{
"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
{
"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
{
"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
{
"event_type": "tick_size_change",
"market": "0x747dc809fb79e1b05be09c42d6179459a58de2ef3e40f02484a4e1260f741f75",
"asset_id": "107505882767731489358349912513945399560393482969656700824895970500493757150417",
"old_tick_size": "0.01",
"new_tick_size": "0.001",
"timestamp": "1782753357257"
}
custom_feature_enabled to include top-of-book and market lifecycle
updates:{
"assets_ids": ["<token_id>"],
"type": "market",
"custom_feature_enabled": true
}
Additional Market Events
Additional Market Events
Best Bid and Ask
{
"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
{
"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
{
"event_type": "market_resolved",
"id": "123456",
"market": "0x747dc809fb79e1b05be09c42d6179459a58de2ef3e40f02484a4e1260f741f75",
"assets_ids": [
"107505882767731489358349912513945399560393482969656700824895970500493757150417",
"7305630249804085635496399869905769372294302716159034447326228509068694952392"
],
"winning_asset_id": "107505882767731489358349912513945399560393482969656700824895970500493757150417",
"winning_outcome": "Yes",
"timestamp": "1782753357257"
}
{
"assets_ids": ["<new_token_id>"],
"operation": "subscribe"
}
{
"assets_ids": ["<old_token_id>"],
"operation": "unsubscribe"
}
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.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.
- TypeScript
- Python
- API
Given a
PublicClient or SecureClient, subscribe to the sports topic to receive
every game update:const stream = await client.subscribe([{ topic: "sports" }]);
for await (const event of stream) {
// event: SportsEvent
}
Sports Event
Sports Event
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;
};
};
{
"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"
}
}
score is a combined "<home>-<away>" string, not separate home and away
fields.Given an
AsyncPublicClient or AsyncSecureClient, subscribe with a
SportsSpec to receive every game update:from polymarket.streams import SportsSpec
async with await client.subscribe(SportsSpec()) as stream:
async for event in stream:
... # event: SportsEvent
Sports Event
Sports Event
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
{
"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"
}
}
score is a combined "<home>-<away>" string, not separate home and away
fields.Connect to the sports WebSocket:Once connected, the server starts streaming every game update. No
subscription frame is required.
Sports messages have no envelope or event-type field. Each message is the
game update object itself, and
wss://sports-api.polymarket.com/ws
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.Sports Event
Sports Event
{
"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"
}
score is a combined "<home>-<away>"
string.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 |
RTDS Streams
The Real-Time Data Service (RTDS) carries reference prices and comments over a shared real-time connection. Subscribe only to the topics your application needs.Crypto Prices
Use crypto price streams to keep reference values current alongside related markets.Trading 15-minute crypto markets? Request a sponsored Chainlink API
key with onboarding support from
Chainlink.
| Source | Supported symbols |
|---|---|
| Binance | btcusdt, ethusdt, solusdt, xrpusdt |
| Chainlink | btc/usd, eth/usd, sol/usd, xrp/usd |
- TypeScript
- Python
- API
Given a
PublicClient or SecureClient, subscribe to the crypto price topics you
need:const stream = await client.subscribe([
{ topic: "prices.crypto.binance", symbols: ["btcusdt", "ethusdt"] },
{ topic: "prices.crypto.chainlink", symbols: ["eth/usd"] },
]);
for await (const event of stream) {
switch (event.topic) {
case "prices.crypto.binance":
// event: CryptoPricesBinanceEvent
break;
case "prices.crypto.chainlink":
// event: CryptoPricesChainlinkEvent
break;
}
}
Crypto Price Events
Crypto Price Events
Binance Price Update
type PriceUpdatePayload = {
symbol: string;
timestamp: EpochMilliseconds;
value: DecimalString;
};
type CryptoPricesBinanceEvent = {
topic: "prices.crypto.binance";
type: "update";
timestamp: EpochMilliseconds;
payload: PriceUpdatePayload;
};
{
"topic": "prices.crypto.binance",
"type": "update",
"timestamp": 1782753357257,
"payload": {
"symbol": "btcusdt",
"timestamp": 1782753357213,
"value": "67234.5"
}
}
Chainlink Price Update
type CryptoPricesChainlinkEvent = {
topic: "prices.crypto.chainlink";
type: "update";
timestamp: EpochMilliseconds;
payload: PriceUpdatePayload;
};
{
"topic": "prices.crypto.chainlink",
"type": "update",
"timestamp": 1782753357257,
"payload": {
"symbol": "eth/usd",
"timestamp": 1782753357213,
"value": "3420.15"
}
}
Given an
AsyncPublicClient or AsyncSecureClient, subscribe with the
crypto price specs you need:from polymarket.streams import CryptoPricesSpec
async with await client.subscribe(
[
CryptoPricesSpec(topic="prices.crypto.binance", symbols=["btcusdt", "ethusdt"]),
CryptoPricesSpec(topic="prices.crypto.chainlink", symbols=["eth/usd"]),
],
) as stream:
async for event in stream:
if event.topic == "prices.crypto.binance":
... # event: CryptoPricesBinanceEvent
elif event.topic == "prices.crypto.chainlink":
... # event: CryptoPricesChainlinkEvent
Crypto Price Events
Crypto Price Events
Binance Price Update
class PriceUpdatePayload:
symbol: str
timestamp: int
value: Decimal
class CryptoPricesBinanceEvent:
topic: Literal["prices.crypto.binance"]
type: Literal["update"]
timestamp: datetime
payload: PriceUpdatePayload
{
"topic": "prices.crypto.binance",
"type": "update",
"timestamp": "2026-06-29T17:15:57.257000Z",
"payload": {
"symbol": "btcusdt",
"timestamp": 1782753357213,
"value": "67234.5"
}
}
Chainlink Price Update
class CryptoPricesChainlinkEvent:
topic: Literal["prices.crypto.chainlink"]
type: Literal["update"]
timestamp: datetime
payload: PriceUpdatePayload
{
"topic": "prices.crypto.chainlink",
"type": "update",
"timestamp": "2026-06-29T17:15:57.257000Z",
"payload": {
"symbol": "eth/usd",
"timestamp": 1782753357213,
"value": "3420.15"
}
}
Connect to RTDS:Once connected, send a subscription frame for the crypto price topics you
need:Binance filters are comma-separated symbols, while Chainlink filters are
JSON strings with a single symbol. Omit
wss://ws-live-data.polymarket.com
RTDS uses an application-level heartbeat. Send the text frame
PING every 5
seconds to maintain the connection.{
"action": "subscribe",
"subscriptions": [
{
"topic": "crypto_prices",
"type": "update",
"filters": "btcusdt,ethusdt"
},
{
"topic": "crypto_prices_chainlink",
"type": "*",
"filters": "{\"symbol\":\"eth/usd\"}"
}
]
}
filters to receive every event
for a topic and type.Crypto Price Events
Crypto Price Events
Binance Price Update
{
"topic": "crypto_prices",
"type": "update",
"timestamp": 1782753357257,
"payload": {
"symbol": "btcusdt",
"timestamp": 1782753357213,
"value": 67234.5
}
}
Chainlink Price Update
{
"topic": "crypto_prices_chainlink",
"type": "update",
"timestamp": 1782753357257,
"payload": {
"symbol": "eth/usd",
"timestamp": 1782753357213,
"value": 3420.15
}
}
Equity Prices
Equity price streams provide Pyth Network reference prices for stocks, ETFs, forex pairs, precious metals, and commodities.Trading equity markets? Subscribe to a Pyth Network data
feed. The first 30 days are
free, then access costs $99 per month.
Subscribe to Equity Prices
- TypeScript
- Python
- API
Given a
PublicClient or SecureClient, subscribe to the equity price topic for the
symbols you need:const stream = await client.subscribe([
{ topic: "prices.equity.pyth", symbol: "AAPL" },
]);
for await (const event of stream) {
if (event.type === "update") {
// event: EquityPricesUpdateEvent
} else {
// event: EquityPricesSubscribeEvent
}
}
Equity Price Events
Equity Price Events
Equity Price Update
type EquityPriceUpdatePayload = {
symbol: string;
value: DecimalString;
timestamp: EpochMilliseconds;
receivedAt?: EpochMilliseconds | null;
isCarriedForward?: boolean | null;
};
type EquityPricesUpdateEvent = {
topic: "prices.equity.pyth";
type: "update";
timestamp: EpochMilliseconds;
payload: EquityPriceUpdatePayload;
};
{
"topic": "prices.equity.pyth",
"type": "update",
"timestamp": 1782753357257,
"payload": {
"symbol": "aapl",
"timestamp": 1782753357213,
"value": "189.4217",
"receivedAt": 1782753357220,
"isCarriedForward": false
}
}
Equity Price Snapshot
type EquityPriceSnapshotPoint = {
timestamp: number;
value: DecimalString;
};
type EquityPriceSubscribePayload = {
symbol: string;
data: EquityPriceSnapshotPoint[];
};
type EquityPricesSubscribeEvent = {
topic: "prices.equity.pyth";
type: "subscribe";
timestamp: EpochMilliseconds;
payload: EquityPriceSubscribePayload;
};
{
"topic": "prices.equity.pyth",
"type": "subscribe",
"timestamp": 1782753357257,
"payload": {
"symbol": "aapl",
"data": [
{ "timestamp": 1782753297000, "value": "189.38" },
{ "timestamp": 1782753357000, "value": "189.42" }
]
}
}
Given an
AsyncPublicClient or AsyncSecureClient, subscribe with an
equity price spec for the symbols you need:from polymarket.streams import EquityPricesSpec
async with await client.subscribe(EquityPricesSpec(symbol="AAPL")) as stream:
async for event in stream:
if event.type == "update":
... # event: EquityPricesUpdateEvent
else:
... # event: EquityPricesSubscribeEvent
Equity Price Events
Equity Price Events
Equity Price Update
class EquityPriceUpdatePayload:
symbol: str
value: Decimal
timestamp: int
received_at: int | None
is_carried_forward: bool | None
class EquityPricesUpdateEvent:
topic: Literal["prices.equity.pyth"]
type: Literal["update"]
timestamp: datetime
payload: EquityPriceUpdatePayload
{
"topic": "prices.equity.pyth",
"type": "update",
"timestamp": "2026-06-29T17:15:57.257000Z",
"payload": {
"symbol": "aapl",
"value": "189.4217",
"timestamp": 1782753357213,
"received_at": 1782753357220,
"is_carried_forward": false
}
}
Equity Price Snapshot
class EquityPriceSnapshotEntry:
timestamp: int
value: Decimal
class EquityPriceSubscribePayload:
symbol: str
data: tuple[EquityPriceSnapshotEntry, ...]
class EquityPricesSubscribeEvent:
topic: Literal["prices.equity.pyth"]
type: Literal["subscribe"]
timestamp: datetime
payload: EquityPriceSubscribePayload
{
"topic": "prices.equity.pyth",
"type": "subscribe",
"timestamp": "2026-06-29T17:15:57.257000Z",
"payload": {
"symbol": "aapl",
"data": [
{ "timestamp": 1782753297000, "value": "189.38" },
{ "timestamp": 1782753357000, "value": "189.42" }
]
}
}
Connect to RTDS:Once connected, send an equity price subscription frame for the symbols
you need:
wss://ws-live-data.polymarket.com
RTDS uses an application-level heartbeat. Send the text frame
PING every 5
seconds to maintain the connection.{
"action": "subscribe",
"subscriptions": [
{
"topic": "equity_prices",
"type": "*",
"filters": "{\"symbol\":\"AAPL\"}"
}
]
}
filters is an optional string, and the server validates that it’s
well-formed JSON: quote both keys and string values. To filter on more than
one symbol, send one subscription entry per symbol. An empty or omitted
filters value means unfiltered.Price updates can include
full_accuracy_value. Prefer this string over the
numeric value when it is present.Equity Price Events
Equity Price Events
Equity Price Update
{
"topic": "equity_prices",
"type": "update",
"timestamp": 1782753357257,
"payload": {
"symbol": "aapl",
"timestamp": 1782753357213,
"value": 189.42,
"full_accuracy_value": "189.4217",
"received_at": 1782753357220,
"is_carried_forward": false
}
}
Equity Price Snapshot
{
"topic": "equity_prices",
"type": "subscribe",
"timestamp": 1782753357257,
"payload": {
"symbol": "aapl",
"data": [
{ "timestamp": 1782753297000, "value": 189.38 },
{ "timestamp": 1782753357000, "value": 189.42 }
]
}
}
Historical Snapshot
When you subscribe to a symbol, the stream first sends its preceding two minutes of price data and then continues with live updates. Use this snapshot to initialize your local state before processing new prices.Supported 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 |
Subscription symbols are case-insensitive, but stream events return symbols in
lowercase.
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.Comments
Use the comments stream to keep conversations and reactions current wherever your application displays Polymarket discussion. Comments can begin a thread or reply to another comment; reply events include the parent comment’s ID.- TypeScript
- Python
- API
Given a Use
PublicClient or SecureClient, subscribe to the comments topic and
select the event types you need:const stream = await client.subscribe([
{
topic: "comments",
types: [
"comment_created",
"comment_removed",
"reaction_created",
"reaction_removed",
],
},
]);
for await (const event of stream) {
switch (event.type) {
case "comment_created":
// event: CommentCreatedEvent
break;
case "comment_removed":
// event: CommentRemovedEvent
break;
case "reaction_created":
// event: ReactionCreatedEvent
break;
case "reaction_removed":
// event: ReactionRemovedEvent
break;
}
}
parentEntityId and parentEntityType to scope the subscription to one
event or market.Comment Events
Comment Events
New Comment
Removed Comment
New Reaction
Removed Reaction
Given an Use
AsyncPublicClient or AsyncSecureClient, subscribe with a
CommentsSpec containing the event types you need:from polymarket.streams import CommentsSpec
async with await client.subscribe(
CommentsSpec(
types=[
"comment_created",
"comment_removed",
"reaction_created",
"reaction_removed",
],
),
) as stream:
async for event in stream:
if event.type == "comment_created":
... # event: CommentCreatedEvent
elif event.type == "comment_removed":
... # event: CommentRemovedEvent
elif event.type == "reaction_created":
... # event: ReactionCreatedEvent
else:
... # event: ReactionRemovedEvent
parent_entity_id and parent_entity_type to scope the subscription to
one event or market.Comment Events
Comment Events
New Comment
class Comment:
id: CommentId
body: str | None
parent_entity_type: str | None
parent_entity_id: EventId | SeriesId | None
parent_comment_id: CommentId | None
user_address: EvmAddress | None
reply_address: EvmAddress | None
created_at: datetime | None
updated_at: datetime | None
media: tuple[CommentMedia, ...] | None
profile: CommentProfile | None
reactions: tuple[Reaction, ...] | None
report_count: int | None
reaction_count: int | None
trade_asset: str | None
class CommentCreatedEvent:
topic: Literal["comments"]
type: Literal["comment_created"]
timestamp: datetime
payload: Comment
{
"topic": "comments",
"type": "comment_created",
"timestamp": "2026-06-29T17:15:57.257000Z",
"payload": {
"id": "1763355",
"body": "That's a good point about the definition.",
"parent_entity_type": "Event",
"parent_entity_id": "18396",
"parent_comment_id": null,
"user_address": "0xce533188d53a16ed580fd5121dedf166d3482677",
"reply_address": "0x0bda5d16f76cd1d3485bcc7a44bc6fa7db004cdd",
"created_at": "2025-07-25T14:49:35.801298Z",
"reaction_count": 0,
"report_count": 0,
"profile": {
"base_address": "0xce533188d53a16ed580fd5121dedf166d3482677",
"display_username_public": true,
"name": "salted.caramel",
"wallet": "0x4ca749dcfa93c87e5ee23e2d21ff4422c7a4c1ee",
"pseudonym": "Adored-Disparity"
}
}
}
Removed Comment
class CommentRemovedPayload:
id: str
body: str | None
parent_entity_type: Literal["Event", "Market"] | None
parent_entity_id: int | None
parent_comment_id: str | None
user_address: EvmAddress | None
reply_address: EvmAddress | None
created_at: datetime | None
updated_at: datetime | None
media: tuple[CommentMedia, ...] | None
profile: CommentProfile | None
reactions: tuple[Reaction, ...] | None
report_count: int | None
reaction_count: int | None
trade_asset: str | None
class CommentRemovedEvent:
topic: Literal["comments"]
type: Literal["comment_removed"]
timestamp: datetime
payload: CommentRemovedPayload
{
"topic": "comments",
"type": "comment_removed",
"timestamp": "2026-06-29T17:15:57.257000Z",
"payload": {
"id": "1763355",
"body": "That's a good point about the definition.",
"parent_entity_type": "Event",
"parent_entity_id": 18396,
"user_address": "0xce533188d53a16ed580fd5121dedf166d3482677"
}
}
New Reaction
class Reaction:
id: str
comment_id: int | None
reaction_type: str | None
icon: str | None
user_address: EvmAddress | None
created_at: datetime | None
profile: CommentProfile | None
class ReactionCreatedEvent:
topic: Literal["comments"]
type: Literal["reaction_created"]
timestamp: datetime
payload: Reaction
{
"topic": "comments",
"type": "reaction_created",
"timestamp": "2026-06-29T17:15:57.257000Z",
"payload": {
"id": "8675309",
"comment_id": 1763355,
"reaction_type": "HEART",
"icon": "❤️",
"user_address": "0xce533188d53a16ed580fd5121dedf166d3482677",
"created_at": "2025-07-25T14:50:04.120000Z"
}
}
Removed Reaction
class ReactionRemovedEvent:
topic: Literal["comments"]
type: Literal["reaction_removed"]
timestamp: datetime
payload: Reaction
{
"topic": "comments",
"type": "reaction_removed",
"timestamp": "2026-06-29T17:15:57.257000Z",
"payload": {
"id": "8675309",
"comment_id": 1763355,
"reaction_type": "HEART",
"user_address": "0xce533188d53a16ed580fd5121dedf166d3482677"
}
}
Connect to RTDS:Once connected, send one subscription entry for each comment event type you
need. Use a
wss://ws-live-data.polymarket.com
RTDS uses an application-level heartbeat. Send the text frame
PING every 5
seconds to maintain the connection.filters string to scope an entry to one entity:{
"action": "subscribe",
"subscriptions": [
{
"topic": "comments",
"type": "comment_created",
"filters": "{\"parentEntityID\":18396,\"parentEntityType\":\"Event\"}"
}
]
}
filters must be well-formed JSON when present: quote keys and string
values. An empty or omitted filters value means you receive every
comment event.Comment Events
Comment Events
New Comment
{
"topic": "comments",
"type": "comment_created",
"timestamp": 1782753357257,
"payload": {
"id": "1763355",
"body": "That's a good point about the definition.",
"parentEntityType": "Event",
"parentEntityID": 18396,
"parentCommentID": null,
"userAddress": "0xce533188d53a16ed580fd5121dedf166d3482677",
"replyAddress": "0x0bda5d16f76cd1d3485bcc7a44bc6fa7db004cdd",
"createdAt": "2025-07-25T14:49:35.801298Z",
"reactionCount": 0,
"reportCount": 0,
"profile": {
"baseAddress": "0xce533188d53a16ed580fd5121dedf166d3482677",
"displayUsernamePublic": true,
"name": "salted.caramel",
"proxyWallet": "0x4ca749dcfa93c87e5ee23e2d21ff4422c7a4c1ee",
"pseudonym": "Adored-Disparity"
}
}
}
Removed Comment
{
"topic": "comments",
"type": "comment_removed",
"timestamp": 1782753357257,
"payload": {
"id": "1763355",
"body": "That's a good point about the definition.",
"parentEntityType": "Event",
"parentEntityID": 18396,
"userAddress": "0xce533188d53a16ed580fd5121dedf166d3482677"
}
}
New Reaction
{
"topic": "comments",
"type": "reaction_created",
"timestamp": 1782753357257,
"payload": {
"id": "8675309",
"commentID": 1763355,
"reactionType": "HEART",
"icon": "❤️",
"userAddress": "0xce533188d53a16ed580fd5121dedf166d3482677",
"createdAt": "2025-07-25T14:50:04.120000Z"
}
}
Removed Reaction
{
"topic": "comments",
"type": "reaction_removed",
"timestamp": 1782753357257,
"payload": {
"id": "8675309",
"commentID": 1763355,
"reactionType": "HEART",
"userAddress": "0xce533188d53a16ed580fd5121dedf166d3482677"
}
}