Skip to main content
The trades channel ("orders") delivers two event types: order_filled and fee_refund.

order_filled

Emitted when an order is filled on-chain.
{
  "type": "event",
  "subscription_id": "sub_2f4b15b33798",
  "data": {
    "event_type": "order_filled",
    "token_id": "61192765571543561192611717014424488264158138188165135910061125994065469709826",
    "token_label": "Up",
    "side": "SELL",
    "market_slug": "btc-updown-15m-1770244200",
    "condition_id": "0x04f954e4f30f5f014f592b4d621768b9c625e3cdaac3c72c8e3762522ecafad8",
    "shares": 2000000,
    "shares_normalized": 2,
    "price": 0.04,
    "tx_hash": "0xf30a29f2497ae5def32105bd6cdac0b6fd9d875cd4107fa02066ebaf42a9f6b6",
    "log_index": "0x21e",
    "title": "Bitcoin Up or Down - February 4, 5:30PM-5:45PM ET",
    "timestamp": 1770244731,
    "order_hash": "0x8bf54f44e5d77432f1698084ada4ad8564b97df25bd9590575aadb98aec121b5",
    "user": "0xe9cbb1c9b3f7f411dd4fdf2ea7afa780c8b4d096",
    "taker": "0x98f36c3d6300b905d00aef4bbae1d5a00874401f",
    "outcome": "Up",
    "outcome_index": 0,
    "complement_token_id": "9876543210...",
    "complement_token_label": "Down",
    "is_neg_risk": false,
    "market_id": "1329542",
    "image": "https://polymarket-upload.s3.us-east-2.amazonaws.com/BTC+fullsize.png",
    "fee": 0.008
  }
}

Field Reference

FieldTypeDescription
event_type"order_filled"
userstringMaker address (order placer)
takerstringTaker address (order filler)
side"BUY" | "SELL"Maker’s side of the trade
pricenumberExecution price in USDC per share
sharesnumberRaw share amount (6 decimal places)
shares_normalizednumberHuman-readable share amount
feenumberFee charged in USDC (see note on fee accuracy below)
token_idstringOutcome token ID
token_labelstring | nullOutcome label (e.g. “Yes”, “Up”)
outcomestring | nullSame as token_label
outcome_indexnumber | nullPosition in the condition’s outcome array. 0 = first outcome (typically Yes/Up), 1 = second (typically No/Down)
complement_token_idstring | nullToken ID of the opposite outcome for the same condition
complement_token_labelstring | nullLabel of the opposite outcome (e.g. “No”, “Down”)
is_neg_riskboolean | nulltrue for neg-risk markets, false for standard CTF markets
condition_idstring | nullMarket condition ID
market_slugstringMarket URL slug
market_idstring | nullInternal market ID
titlestring | nullMarket title
imagestring | nullMarket image URL
order_hashstring | nullOrder hash
tx_hashstringTransaction hash
log_indexstringLog index within the transaction (hex)
timestampnumberUnix timestamp in seconds

fee_refund

Emitted when a maker fee rebate is processed on-chain.
{
  "type": "event",
  "subscription_id": "sub_2f4b15b33798",
  "data": {
    "event_type": "fee_refund",
    "user": "0x47a51f21d7424d62259479f4abe98f4443946834",
    "token_id": "53031995840519349287926798501784281703112543680473469697119005679182720764080",
    "condition_id": "0xdfb2f9d3ed88bbc4bb7c53aeacfa54fca32259ac94dec52d1503182b762ae5f1",
    "market_slug": "btc-updown-15m-1770242400",
    "title": "Bitcoin Up or Down - February 4, 5:00PM-5:15PM ET",
    "order_hash": "0xbda8ab86c90fc5f366531d103f433b2fbf99db523438b8b1ab188d7038b74b69",
    "tx_hash": "0x97b2ae33188131fceafac5f7f0d36741abc9ccdd07115fe5faa84896e05d9314",
    "refund": 9.9904,
    "fee_charged": 0.0096
  }
}

Field Reference

FieldTypeDescription
event_type"fee_refund"
userstringAddress that received the refund
token_idstringOutcome token ID
condition_idstring | nullMarket condition ID
market_slugstring | nullMarket URL slug
titlestring | nullMarket title
order_hashstringThe order hash this refund applies to
tx_hashstringTransaction hash
refundnumberUSDC amount refunded to the maker
fee_chargednumberFinal net fee in USDC after the refund

Understanding Fee Refunds

Polymarket implements a maker fee rebate program. When a trade executes on-chain, the OrderFilled event reports the full gross fee. Immediately after, the exchange’s Fee Module processes a rebate for the maker — this is the FeeRefunded event. In practice:
  1. An order_filled event arrives with a fee field representing the gross fee initially charged.
  2. A fee_refund event for the same order_hash arrives 2-5ms later (within the same block, typically in the same transaction). In rare cases it may be up to 50ms later, but never more.
  3. The maker’s actual net fee is: fee_refund.fee_charged (or equivalently, order_filled.fee - fee_refund.refund).
If you do not need exact fee accounting, you can safely ignore fee_refund events. The fee field on order_filled is still directionally correct and useful for most purposes. Fee refund events are only necessary if your application requires precise net fee calculations (e.g. PnL tracking, cost basis accounting).
Fee refund events are delivered on the same trades channel and respect the same subscription filters (users, condition_ids, market_slugs, wildcard). You can correlate them to their corresponding trade via the order_hash and tx_hash fields.

Example: Processing Trades

ws.onmessage = (event) => {
  const msg = JSON.parse(event.data);

  if (msg.type === 'event') {
    const data = msg.data;

    if (data.event_type === 'order_filled') {
      const value = data.shares_normalized * data.price;
      console.log(`${data.side} ${data.outcome} ${data.shares_normalized} @ ${data.price}`);
      console.log(`Market: ${data.title}`);
      console.log(`Value: $${value.toFixed(2)}`);
      console.log(`Maker: ${data.user}`);
      console.log(`Taker: ${data.taker}`);
    }

    if (data.event_type === 'fee_refund') {
      console.log(`Fee refund: $${data.refund} for order ${data.order_hash}`);
      console.log(`Net fee: $${data.fee_charged}`);
    }
  }
};