WebSockets

Messages & lifecycle

The shape of trade events, how to stop a stream, and how the connection stays healthy.

Event messages

Each event is a JSON frame carrying the event type, its source, the delivery timestamp, and a data object with the trade. Here is a live polymarket.trade event (long hashes abbreviated):

JSON · server → client
{
  "type": "polymarket.trade",
  "source": "polymarket-trade-scraper",
  "timestamp": "2026-05-27T13:50:00.167247+00:00",
  "data": {
    "id": "0x8902f2…498832_0x31ba8c…a5aa09",
    "side": "BUY",
    "size": 11,
    "price": 0.53,
    "timestamp": "2026-05-27T13:49:52+00:00",
    "transaction_hash": "0x8902f299…d6d498832",
    "order_hash": "0x31ba8c8c…454aa5aa09",
    "block_number": 87514326,
    "condition_id": "0x9ad19824…2d7f2d9",
    "asset": "67025362…363793",
    "title": "Bitcoin Up or Down - May 27, 9:50AM-9:55AM ET",
    "slug": "btc-updown-5m-1779889800",
    "event_slug": "btc-updown-5m",
    "outcome": "Up",
    "outcome_index": 0,
    "icon": "https://polymarket-upload.s3…/BTC+fullsize.png",
    "maker": "0x55338c…d1b8220",
    "taker": "0x6833c0…1b5cfe1",
    "proxy_wallet": "0x55338c…d1b8220",
    "name": null,
    "pseudonym": null,
    "bio": null,
    "profile_image": null,
    "profile_image_optimized": null
  }
}

Filterable fields

The fields you can filter on (from /event-types). Every event also carries the additional non-filterable fields shown in the payload above.

FieldTypeDescription
proxy_walletstringTrader's proxy wallet
slugstringMarket slug
condition_idstringMarket condition ID
event_slugstringParent event slug
outcomestringOutcome traded (e.g. Up, No)
outcome_indexintegerIndex of the traded outcome
sidestringTrade direction — BUY or SELL
assetstringOutcome token (asset) ID
makerstringMaker wallet address
takerstringTaker wallet address
transaction_hashstringOn-chain transaction hash
order_hashstringOn-chain order hash

Unsubscribe

Stop one or more streams by sending an unsubscribe frame with the subscription_ids returned when you subscribed. The server confirms with an unsubscribed acknowledgement.

JSON · client → server
{
  "action": "unsubscribe",
  "subscription_ids": ["cede7755-c0a6-41b8-b316-ca4377dedb5d"]
}
JSON · server → client
{
  "action": "unsubscribed",
  "subscription_ids": ["cede7755-c0a6-41b8-b316-ca4377dedb5d"]
}

Connection lifecycle

Heartbeat

Connections are kept healthy by a built-in ping/pong heartbeat. Most WebSocket libraries respond to pings automatically, so there's nothing to implement — your stream stays alive as long as your client is connected.

Reconnection

Connections are long-lived. For a resilient client, reconnect automatically with exponential backoff and re-send your subscribe frames once reconnected — the standard pattern for any streaming integration. A close with code 4001 is simply a cue to reconnect to a fresh upstream feed, and deploys roll out with graceful connection draining so reconnects stay clean. You can confirm gateway health any time with GET /health (returns 200 OK). The SDK does all of this for you.