Skip to main content
Room ID: polymarket_trades
Endpoint: wss://api.struct.to/ws
Rate: 0.002 credits per message
Stream real-time Polymarket trades as they happen. All filters are optional, and if none are provided the room auto-subscribes to every trade.
Related guides: Mirroring a trader from the mempool uses this room’s status filter for pending vs confirmed fills, and TradingView charts for Polymarket feeds it into live OHLC bars.

Subscribe

All filters are optional. You can combine multiple filters to narrow the stream. A maximum of 500 total filters is allowed per client. If all filters are empty and subscribe_all is false, the room automatically subscribes to all trades.

Filters

FilterTypeRequiredDescription
condition_idsstring[]NoFilter by market condition IDs
market_slugsstring[]NoFilter by market slug
event_slugsstring[]NoFilter by event slug
position_idsstring[]NoFilter by outcome token IDs
tradersstring[]NoFilter by wallet addresses (lowercase 0x-prefixed)
trade_typesstring[]NoFilter by trade type: OrderFilled, OrdersMatched, Redemption, Merge, Split, etc.
statusstringNoOne of confirmed (default), pending, or all
subscribe_allbooleanNoSubscribe to every trade with no filters

Example

{
  "type": "join_room",
  "payload": {
    "room_id": "polymarket_trades"
  }
}
{
  "type": "room_message",
  "payload": {
    "room_id": "polymarket_trades",
    "message": {
      "action": "subscribe",
      "condition_ids": ["0xabc123..."]
    }
  }
}

Response

{
  "type": "trade_stream_subscribe_response",
  "room_id": "polymarket_trades",
  "data": {
    "condition_ids": ["0xabc123..."],
    "market_slugs": [],
    "event_slugs": [],
    "position_ids": [],
    "traders": [],
    "trade_types": [],
    "rejected": []
  }
}

Events

trade_stream_update

The payload is a discriminated union based on the trade_type field. Each variant includes different fields. Below is an example of the most common type, OrderFilled.

OrderFilled / OrdersMatched

{
  "type": "trade_stream_update",
  "room_id": "polymarket_trades",
  "status": "confirmed",
  "data": {
    "trade_type": "OrderFilled",
    "id": "0xabc123def456",
    "hash": "0xdeadbeef1234567890",
    "block": 65000000,
    "confirmed_at": 1743500000,
    "log_index": 42,
    "block_index": 3,
    "trader": {
      "address": "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045",
      "name": null,
      "pseudonym": "vitalik.eth",
      "profile_image": null,
      "x_username": null,
      "verified_badge": false
    },
    "taker": "0x1234567890abcdef1234567890abcdef12345678",
    "side": "Buy",
    "condition_id": "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
    "position_id": "12345678901234567",
    "outcome": "Yes",
    "outcome_index": 0,
    "slug": "will-bitcoin-hit-100k",
    "event_slug": "bitcoin-price-markets",
    "image_url": "https://example.com/markets/bitcoin-100k.png",
    "usd_amount": 1500.50,
    "shares_amount": 2307.69,
    "price": 0.65,
    "probability": 0.65,
    "fee": 3.0,
    "fee_shares": 4.62,
    "fee_pct": 0.002,
    "exchange": "NegRiskExchange",
    "builder_code": "0x0000000000000000000000000000000000000000000000000000000000000000",
    "builder_fee": 0.0
  }
}
builder_code is the lower-cased 0x... bytes32 identifier of the integrator that brokered the order (CLOB v2 only). 0x0000… means the order was placed directly through Polymarket. Both builder_code and builder_fee are omitted on v1 trades. See Fetching trades by builder code.

Redemption

{
  "type": "trade_stream_update",
  "room_id": "polymarket_trades",
  "status": "confirmed",
  "data": {
    "trade_type": "Redemption",
    "id": "0xredeem123",
    "hash": "0xredeemhash",
    "block": 65000100,
    "confirmed_at": 1743500100,
    "trader": {
      "address": "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045",
      "name": null,
      "pseudonym": "vitalik.eth",
      "profile_image": null,
      "x_username": null,
      "verified_badge": false
    },
    "condition_id": "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
    "outcome": "Yes",
    "outcome_index": 0,
    "slug": "will-bitcoin-hit-100k",
    "event_slug": "bitcoin-price-markets",
    "image_url": "https://example.com/markets/bitcoin-100k.png",
    "usd_amount": 1000.0,
    "winning_outcome_index": 0,
    "position_details": [
      { "position_id": "12345678901234567", "outcome_index": 0, "outcome": "Yes", "amount": "1000" }
    ],
    "exchange": "NegRiskExchange"
  }
}

Merge

{
  "type": "trade_stream_update",
  "room_id": "polymarket_trades",
  "status": "confirmed",
  "data": {
    "trade_type": "Merge",
    "id": "0xmerge123",
    "hash": "0xmergehash",
    "block": 65000200,
    "confirmed_at": 1743500200,
    "trader": {
      "address": "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045",
      "name": null,
      "pseudonym": "vitalik.eth",
      "profile_image": null,
      "x_username": null,
      "verified_badge": false
    },
    "condition_id": "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
    "slug": "will-bitcoin-hit-100k",
    "event_slug": "bitcoin-price-markets",
    "image_url": "https://example.com/markets/bitcoin-100k.png",
    "usd_amount": 500.0,
    "position_details": [
      { "position_id": "12345678901234567", "outcome_index": 0, "outcome": "Yes", "amount": "500" },
      { "position_id": "98765432109876543", "outcome_index": 1, "outcome": "No", "amount": "500" }
    ],
    "exchange": "NegRiskExchange"
  }
}

Split

{
  "type": "trade_stream_update",
  "room_id": "polymarket_trades",
  "status": "confirmed",
  "data": {
    "trade_type": "Split",
    "id": "0xsplit123",
    "hash": "0xsplithash",
    "block": 65000300,
    "confirmed_at": 1743500300,
    "trader": {
      "address": "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045",
      "name": null,
      "pseudonym": "vitalik.eth",
      "profile_image": null,
      "x_username": null,
      "verified_badge": false
    },
    "condition_id": "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
    "slug": "will-bitcoin-hit-100k",
    "event_slug": "bitcoin-price-markets",
    "image_url": "https://example.com/markets/bitcoin-100k.png",
    "usd_amount": 750.0,
    "position_details": [
      { "position_id": "12345678901234567", "outcome_index": 0, "outcome": "Yes", "amount": "750" },
      { "position_id": "98765432109876543", "outcome_index": 1, "outcome": "No", "amount": "750" }
    ],
    "exchange": "NegRiskExchange"
  }
}

PositionsConverted

{
  "type": "trade_stream_update",
  "room_id": "polymarket_trades",
  "status": "confirmed",
  "data": {
    "trade_type": "PositionsConverted",
    "id": "0xconvert123",
    "hash": "0xconverthash",
    "block": 65000400,
    "confirmed_at": 1743500400,
    "trader": {
      "address": "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045",
      "name": null,
      "pseudonym": "vitalik.eth",
      "profile_image": null,
      "x_username": null,
      "verified_badge": false
    },
    "market_id": "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
    "index_set": "3",
    "shares_amount": 200.0,
    "exchange": "NegRiskExchange"
  }
}

Cancelled

{
  "type": "trade_stream_update",
  "room_id": "polymarket_trades",
  "status": "confirmed",
  "data": {
    "trade_type": "Cancelled",
    "id": "0xcancel123",
    "hash": "0xcancelhash",
    "block": 65000500,
    "confirmed_at": 1743500500,
    "order_hash": "0xorderhash123",
    "slug": "will-bitcoin-hit-100k",
    "event_slug": "bitcoin-price-markets",
    "image_url": "https://example.com/markets/bitcoin-100k.png",
    "exchange": "NegRiskExchange"
  }
}

Oracle Lifecycle

Covers Initialization, Proposal, Dispute, Settled, Resolution, ConditionResolution, Reset, Flag, Unflag, Pause, Unpause, ManualResolution, and NegRiskOutcomeReported.
{
  "type": "trade_stream_update",
  "room_id": "polymarket_trades",
  "status": "confirmed",
  "data": {
    "trade_type": "Resolution",
    "id": "0xoracle123",
    "hash": "0xoraclehash",
    "block": 65000600,
    "confirmed_at": 1743500600,
    "oracle_contract": "0xoraclecontract",
    "condition_id": "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
    "slug": "will-bitcoin-hit-100k",
    "image_url": "https://example.com/markets/bitcoin-100k.png",
    "assertion_id": "0xassertion123",
    "settled_price": 1,
    "settlement_resolution": true
  }
}

RegisterToken

{
  "type": "trade_stream_update",
  "room_id": "polymarket_trades",
  "status": "confirmed",
  "data": {
    "trade_type": "RegisterToken",
    "id": "0xregtoken123",
    "hash": "0xregtokenhash",
    "block": 65000700,
    "confirmed_at": 1743500700,
    "condition_id": "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
    "token0": "0xtoken0address",
    "token1": "0xtoken1address",
    "slug": "will-bitcoin-hit-100k",
    "event_slug": "bitcoin-price-markets",
    "image_url": "https://example.com/markets/bitcoin-100k.png",
    "exchange": "NegRiskExchange"
  }
}

MakerRebate / Reward / Yield

pUSD credit paid directly to a trader wallet. The three variants share the same payload shape and differ only by trade_type. shares_amount, price, fee, fee_shares, and fee_pct are always 0 for payout credits, and taker is the payout distributor address rather than a counterparty.
{
  "type": "trade_stream_update",
  "room_id": "polymarket_trades",
  "status": "confirmed",
  "data": {
    "trade_type": "MakerRebate",
    "id": "0xrebate123",
    "hash": "0xrebatehash",
    "block": 65000800,
    "confirmed_at": 1743500800,
    "log_index": 12,
    "block_index": 1,
    "trader": {
      "address": "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045",
      "name": null,
      "pseudonym": "vitalik.eth",
      "profile_image": null,
      "x_username": null,
      "verified_badge": false
    },
    "taker": "0xpayoutdistributoraddress",
    "usd_amount": 12.5,
    "shares_amount": 0,
    "price": 0,
    "fee": 0,
    "fee_shares": 0,
    "fee_pct": 0,
    "exchange": 0
  }
}
Pending trades: Fields unavailable from mempool (block, confirmed_at, log_index, block_index, order_hash, taker, fee, fee_shares, fee_pct) are omitted. received_at (Unix milliseconds) is included instead.
Last modified on June 8, 2026