Fills Channel

Real-time fill feed for authenticated users.

This channel provides per-account trade data with realized PnL — the real-time counterpart to the REST /v1/trade-history endpoint.

Authentication Required: Yes — the channel is always scoped to the authenticated account.

Subscribe

{
  "method": "subscribe",
  "params": {
    "channel": "fills",
    "market_ids": [1, 2]
  }
}
ParameterTypeRequiredDescription
market_idsnumber[]NoFilter by market IDs. Empty = all markets
makersstring[]NoAccount filter. Omit it — the channel uses your authenticated account

Authentication

Authenticate before subscribing — see Authentication for the EIP-712 flows:

{
  "method": "auth_v2",
  "params": {
    "account": "0x1234567890123456789012345678901234567890",
    "signer": "0xabcdefabcdefabcdefabcdefabcdefabcdefabcd",
    "message": "WebSocket Authentication",
    "nonce": "deadbeefcafebabe0123456789abcdef0123456789abcdef0123456789abcdef",
    "signature": "0x..."
  }
}

Message Format

Update

Sent when a trade executes where you are the maker or the taker. There is no snapshot — historical fills come from the REST API.

{
  "channel": "fills",
  "type": "update",
  "market_id": "1",
  "data": {
    "id": "0x00000000000058c8000000000126f109000000000000027b-0x0000000400001157000000000126f0fc000000000000026d",
    "market_id": "1",
    "order_id": "0x00000000000058c8000000000126f109000000000000027b",
    "client_order_id": "4078518646",
    "side": "BUY",
    "price": "63232.6",
    "size": "0.000273",
    "fee": "0.005178",
    "liquidity_indicator": "TAKER",
    "time": "1786935048000000000",
    "is_liquidation": false,
    "is_otc": false,
    "realized_pnl": "1.234567",
    "realized_pnl_percentage": "2.5",
    "avg_price": "62000.1",
    "position_side": "BUY",
    "leverage": "10",
    "margin_mode": 0,
    "blockchain_data": {
      "tx_hash": "0x68327dc379122ea0caf5572e2aec8d4ec3ce3b2df4ccc44d73f20755c25e3d05",
      "block_number": 19329289,
      "log_index": 634
    }
  },
  "tx_hash": "0x68327dc379122ea0caf5572e2aec8d4ec3ce3b2df4ccc44d73f20755c25e3d05",
  "block_number": 19329289,
  "log_index": 634,
  "worker_timestamp": "1786935049200112233"
}

Update Message Fields

FieldTypeDescription
channelstringAlways "fills"
typestringAlways "update"
market_idstringMarket ID
dataobjectFill object (see below)
tx_hashstringTransaction hash
block_numbernumberBlockchain block number
log_indexnumberLog index within the block
worker_timestampstringServer time in nanoseconds

There is no timestamp or block_timestamp field on this channel — data.time carries the block time of the trade.

Fill Object Fields

FieldTypeDescription
idstringUnique trade ID — "<maker_order_id>-<taker_order_id>", both 24-byte hex
market_idstringMarket ID
order_idstringYour order's composite ID, hex (0x…)
client_order_idstringYour client order ID, if one was sent
sidestringYour trade side: "BUY" or "SELL"
pricestringTrade price, decimal
sizestringTrade size, decimal
feestringFee you paid, decimal USDC
liquidity_indicatorstring"MAKER" or "TAKER"
timestringBlock time of the trade (nanoseconds)
is_liquidationbooleanThis fill came from a liquidation
is_otcbooleanThis fill came from an OTC vault trade
realized_pnlstringRealized PnL from this fill, decimal. Absent when nothing was realized
realized_pnl_percentagestringRealized PnL as a percentage, decimal. Absent when nothing was realized
avg_pricestringAverage entry price of the position after the fill, decimal
position_sidestringPosition side after the fill: "BUY", "SELL", or "" when flat
leveragestringLeverage after the fill, decimal
margin_modenumber0 = cross, 1 = isolated — a number, not a string
blockchain_dataobjectBlock metadata, mirroring the envelope fields

Optional fields (client_order_id, the PnL fields, avg_price, position_side, leverage, blockchain_data) are omitted entirely when empty rather than sent as "".

Blockchain Data Object

FieldTypeDescription
tx_hashstringTransaction hash
block_numbernumberBlock number
log_indexnumberLog index within block

Liquidity Indicator

ValueDescription
MAKERYou provided liquidity (your order was resting on book)
TAKERYou removed liquidity (your order crossed the spread)

Position Side

ValueDescription
BUYLong position after this trade
SELLShort position after this trade
""Flat (no position) after this trade

PnL Calculation

  • realized_pnl: realized profit/loss from this fill, computed as After.RealizedPNL − Before.RealizedPNL
  • realized_pnl_percentage: percentage relative to the position's entry cost

Both are present only when the fill actually realized PnL — that is, when the position shrank or flipped.

Examples

Subscribe to all fills

{
  "method": "subscribe",
  "params": {
    "channel": "fills"
  }
}

Subscribe to specific markets

{
  "method": "subscribe",
  "params": {
    "channel": "fills",
    "market_ids": [1, 2]
  }
}

Unsubscribe

{
  "method": "unsubscribe",
  "params": {
    "channel": "fills"
  }
}

Error Responses

Subscribing without authenticating first:

{
  "type": "subscribed",
  "method": "subscribe",
  "status": "error",
  "channel": "fills",
  "message": "Failed to subscribe to fills: no authenticated account for fills channel"
}

Note that type still says subscribed — it echoes the request, not the outcome. Read status.

Testing with wscat

# Connect (mainnet)
wscat -c wss://ws.rise.trade/ws

# Authenticate first (see the Authentication page for how to build the signature)
{"method":"auth_v2","params":{"account":"0x...","signer":"0x...","message":"WebSocket Authentication","nonce":"...","signature":"0x..."}}

# Subscribe to all fills
{"method":"subscribe","params":{"channel":"fills"}}

# Subscribe to market 1 only (BTC/USDC)
{"method":"subscribe","params":{"channel":"fills","market_ids":[1]}}

# Unsubscribe
{"method":"unsubscribe","params":{"channel":"fills"}}

Notes

No Snapshot

Nothing is sent at subscription time. Historical fills are available from GET /v1/trade-history.

Price Format

All price, size and fee fields are decimal strings (human-readable), not wei.

Real-time Delivery

Fills are broadcast as soon as the match event is processed from the chain. There is no batching or throttling.

Private Channel

Authenticate before subscribing. The channel is meant to carry your own fills only.

Difference from Trades Channel

AspectTrades ChannelFills Channel
AuthenticationNot requiredRequired
ScopeAll trades (public)Your fills only (private)
PnL DataNoYes
Position DataNoYes (side, leverage, margin)
Order IDBoth maker/takerYour order ID only
FeeBoth maker/takerYour fee only