WebSocket URL: wss://wss.liquiditytech.com/v1/private
Three push channels report forced liquidation in real time on the User Data connection. Like every other User Data channel, they are activated automatically after a successful login — no explicit subscription is required. See Overview for the connection URL, login payload and heartbeat.
See Liquidation Event for what the event types and node types mean, and Get Liquidation Event to pull the full event afterwards.
Which channel do I need?
| Channel | Granularity | Pushed when | Delivered to |
|---|---|---|---|
LiquidationEvent | Node — one push per step of the liquidation, with full account, asset, position and order snapshots | The liquidation process advances to a new node | The connection of the Portfolio being liquidated |
LiquidationPosition | Order — one push per liquidation order, with the affected position | Each liquidation order is archived | The connection of the Portfolio being liquidated |
LiquidationPositionByUser | Order — identical payload to LiquidationPosition | Each liquidation order is archived | The connection of the main account, covering all its Sub Portfolios |
In practice: use LiquidationEvent to follow the liquidation as a process (what stage is it at, is the account recovering), and LiquidationPosition to react to individual fills as they land. If you are a main account monitoring many Sub Portfolios, LiquidationPositionByUser saves you from holding one connection per Sub Portfolio.
liquidationEventId is the same across all three channels, so you can correlate them — and use it to call Get Liquidation Event.
MarginCallon the User Data stream fires before liquidation begins, whenuniMMRapproaches the threshold. If you want to act rather than only record, that is the channel to watch.
LiquidationEvent
Pushed each time the liquidation process advances to a new node. Each push is the snapshot for one node — the same content the nodes[] array of Get Liquidation Event returns, but delivered as it happens, with the event-level summary fields repeated on every push.
Which snapshot fields are present depends on nodeType — see the node type table on Liquidation Event.
{
"channel": "LiquidationEvent",
"data": {
"liquidationEventId": "2196234614019650",
"portfolioId": "2188510950055490",
"exchangeType": "BINANCE",
"eventType": "POSITION_LIQUIDATION",
"nodeId": "2196234681118274",
"nodeType": "COMPLETED",
"createAt": "1785927152750",
"updateAt": "1785927152750",
"triggerUniMmr": "-0.130596039262601086",
"totalPositionsLiquidated": 1,
"totalClosedPnl": "30.009",
"totalLiqFee": "0",
"account": {
"portfolioId": "2188510950055490",
"exchangeType": "BINANCE",
"equity": "0.00861129",
"marginValue": "0.00856823355",
"frozenMargin": "0",
"perpMargin": "0",
"debtMargin": "0",
"openLossMargin": "0",
"validMargin": "0.00856823355",
"availableMargin": "0.00856823355",
"maintainMargin": "0",
"positionValue": "0",
"uniMmr": "999999",
"accountStatus": "NORMAL",
"upnl": "0",
"createAt": "1784085671990",
"updateAt": "1785927152750"
},
"assets": [
{
"portfolioId": "2188510950055490",
"exchangeType": "BINANCE",
"businessType": "UNI",
"coin": "USDT",
"available": "0.00861129",
"frozen": "0",
"balance": "0.00861129",
"equity": "0.00861129",
"overdraw": "0",
"marginValue": "0.00856823355",
"debt": "0",
"upnl": "0"
}
],
"positions": [
{
"portfolioId": "2188510950055490",
"positionId": "20210633186440770",
"sym": "BINANCE_PERP_SOL_USDT",
"positionSide": "NONE",
"positionQty": "0",
"positionMargin": "0",
"positionMM": "0",
"unrealizedPNL": "0",
"avgPrice": "0",
"markPrice": "0",
"leverage": "10",
"updateAt": "1785927151886"
}
]
}
}The example above is a terminal COMPLETED node: the position is flat, uniMmr is back to the 999999 no-positions sentinel and accountStatus has returned to NORMAL. triggerUniMmr is negative because valid margin had already fallen below zero when the event was triggered.
| Field | Type | Remark |
|---|---|---|
channel | String | Channel name: LiquidationEvent |
data | Object | Node snapshot |
>liquidationEventId | String | Liquidation event ID. Constant across every node of the same event. |
>portfolioId | String | Portfolio being liquidated |
>exchangeType | String | Venue the event is taking place on: BINANCE, OKX, EDX |
>eventType | String | CANCELLATION (orders cancelled only, no position closed) or POSITION_LIQUIDATION (positions force-closed) |
>nodeId | String | Node execution ID, unique within the event |
>nodeType | String | What this step did. See the node type table on Liquidation Event. |
>roundSeq | Integer | Position-reduction round, starting at 1. Only present on POSITION_REDUCE nodes. |
>createAt | String | Timestamp when this node started (milliseconds) |
>updateAt | String | Timestamp of this update (milliseconds) |
>triggerUniMmr | String | The uniMMR that tripped the liquidation trigger. Only present for POSITION_LIQUIDATION. May be negative, which means valid margin was already below zero. |
>totalPositionsLiquidated | Integer | Number of positions force-closed across the whole event so far. Only present for POSITION_LIQUIDATION. |
>totalClosedPnl | String | Total realized PnL from the closed perpetual positions, in USDT. Only present for POSITION_LIQUIDATION. |
>totalLiqFee | String | Total liquidation fees charged across the event so far, in USDT. Only present for POSITION_LIQUIDATION. |
>account | Object | Account snapshot at this node. Omitted on the POSITION_LIQUIDATED container node. See below. |
>assets | Array | Asset snapshots at this node, one entry per coin. Omitted on the POSITION_LIQUIDATED container node. See below. |
>positions | Array | Position snapshots at this node. Omitted on the container node and on the order-cancellation nodes. See below. |
>orders | Array | Snapshots of the open orders cancelled by this node. Only present on CANCEL_OPEN_ORDERS and CANCEL_ALL_ORDERS nodes. See below. |
account
| Field | Type | Remark |
|---|---|---|
portfolioId | String | Portfolio ID |
exchangeType | String | Venue this account state applies to: BINANCE, OKX, EDX |
equity | String | Total account equity on this venue, valued in USDT-equivalent (including cash balance and PnL) |
marginValue | String | Total margin value on this venue |
frozenMargin | String | Locked margin (e.g. for open orders or positions), unavailable for new trades or withdrawal |
perpMargin | String | Margin allocated specifically to perpetual contracts |
debtMargin | String | Margin used to cover borrowing and negative balances |
openLossMargin | String | Margin portion reserved to cover current open losses |
validMargin | String | marginValue - openLossMargin |
availableMargin | String | Margin available for opening new positions or for withdrawal |
maintainMargin | String | Minimum margin required across all positions to avoid liquidation |
positionValue | String | Notional value of all open positions on this venue |
uniMmr | String | validMargin / maintainMargin. Unified maintenance margin ratio, expressed as a decimal where 1 = 100%. A forced liquidation is triggered when it falls below 1. Returns the sentinel 999999 when the account has no maintenance margin requirement. |
accountStatus | String | Account status at this node: NORMAL (back within margin requirements), LIQUIDATION (liquidation in progress), TAKEOVER (position taken over by LTP) |
upnl | String | Unrealized profit and loss of the account, in USDT |
createAt | String | Timestamp when the account was created (milliseconds) |
updateAt | String | Timestamp of this account snapshot (milliseconds) |
assets[]
One entry per coin held on the venue at this node.
| Field | Type | Remark |
|---|---|---|
portfolioId | String | Portfolio ID |
exchangeType | String | Venue this balance is held on: BINANCE, OKX, EDX |
businessType | String | Account type. Returns UNI for all assets in the Portfolio. |
coin | String | Coin symbol, e.g. USDT, BTC |
available | String | Amount available for placing new orders or withdrawing |
frozen | String | Amount locked due to open orders or pending operations |
balance | String | Total balance of this coin including frozen funds |
equity | String | Equity of this coin = balance + unrealized PnL from open positions |
overdraw | String | Amount overdrawn beyond the available balance |
marginValue | String | Value of this coin counted as collateral margin (in USDT) |
debt | String | Outstanding borrowed amount of this coin not yet repaid. 0 if nothing is borrowed |
upnl | String | Unrealized profit and loss from open positions denominated in this coin |
positions[]
| Field | Type | Remark |
|---|---|---|
portfolioId | String | Portfolio ID |
positionId | String | Internal position ID for this symbol and side within the Portfolio |
sym | String | Unified symbol identifier, e.g. BINANCE_PERP_BTC_USDT |
positionSide | String | Position side: NONE in one-way mode, LONG or SHORT in hedge mode |
positionQty | String | Position quantity. Positive = long, negative = short. Unit varies by venue: contracts on OKX, base currency on BINANCE |
positionMargin | String | Margin currently allocated to this position |
positionMM | String | Maintenance margin required to keep this position open |
unrealizedPNL | String | Unrealized profit or loss on this position, based on the mark price at this node |
avgPrice | String | Volume-weighted average entry price of this position |
markPrice | String | Mark price used for the PnL and liquidation check at this node |
leverage | String | Leverage applied to this position at the time |
updateAt | String | Timestamp of this position snapshot (milliseconds) |
orders[]
Snapshots of the open orders cancelled by this node, as they were immediately before cancellation.
| Field | Type | Remark |
|---|---|---|
portfolioId | String | Portfolio ID |
orderId | String | Order ID |
sym | String | Unified symbol identifier, e.g. BINANCE_PERP_BTC_USDT |
side | String | Order side: BUY or SELL |
orderType | String | Order type: LIMIT or MARKET |
orderState | String | State the order was in when the snapshot was taken, e.g. NEW, PARTIALLY_FILLED |
orderQty | String | Order quantity. Unit varies by venue: contracts on OKX, base currency on BINANCE |
executedQty | String | Quantity already filled before the order was cancelled |
limitPrice | String | Order price. 0 for market orders |
createAt | String | Timestamp when the order was placed (milliseconds) |
updateAt | String | Timestamp of this order snapshot (milliseconds) |
LiquidationPosition
Pushed each time a liquidation order is archived, with a snapshot of the position it affected. Where LiquidationEvent tells you which stage the liquidation has reached, this channel tells you what each individual liquidation fill did to your position — one push per order.
{
"channel": "LiquidationPosition",
"data": {
"liquidationEventId": "7391234567890001",
"portfolioId": "1702884522340000",
"orderId": "1703213979730000",
"positionId": "1704179813908000",
"exchangeType": "BINANCE",
"sym": "BINANCE_PERP_BTC_USDT",
"positionSide": "LONG",
"reduceQty": "0.05",
"closedPnl": "-5.00",
"markPrice": "50000.00",
"totalTradingFee": "1.25",
"liqFee": "0.50",
"positionMode": "NET",
"leverage": 10,
"uniMmr": "0.52",
"validMargin": "7800.00",
"maintainMargin": "2000.00",
"createAt": 1700000030000,
"updateAt": 1700000030000
}
}| Field | Type | Remark |
|---|---|---|
channel | String | Channel name: LiquidationPosition |
data | Object | Liquidation order and position snapshot |
>liquidationEventId | String | Liquidation event this order belongs to. Use it to pull the full event from Get Liquidation Event. |
>portfolioId | String | Portfolio being liquidated |
>orderId | String | ID of the liquidation order that was just archived |
>positionId | String | Internal position ID for this symbol and side within the Portfolio |
>exchangeType | String | Venue the order was placed on: BINANCE, OKX, EDX |
>sym | String | Unified symbol identifier, e.g. BINANCE_PERP_BTC_USDT |
>positionSide | String | Position side: NONE in one-way mode, LONG or SHORT in hedge mode |
>reduceQty | String | Quantity this order removed from the position. Unit varies by venue: contracts on OKX, base currency on BINANCE |
>closedPnl | String | Realized PnL from the quantity closed by this order, in USDT |
>markPrice | String | Mark price at the time of the push |
>totalTradingFee | String | Total trading fee charged on this order, in USDT. Nullable |
>liqFee | String | Liquidation fee charged on this order, in USDT |
>positionMode | String | Position mode on this venue: NET (one-way) or BOTH (dual-side) |
>leverage | Integer | Leverage applied to this position at the time |
>uniMmr | String | validMargin / maintainMargin. Unified maintenance margin ratio, expressed as a decimal where 1 = 100%. A forced liquidation is triggered when it falls below 1. Watch this field across successive pushes to see whether the account is recovering. |
>validMargin | String | marginValue - openLossMargin |
>maintainMargin | String | Minimum margin required across all positions to avoid liquidation |
>createAt | Long | Timestamp when the liquidation order was placed (milliseconds) |
>updateAt | Long | Timestamp of this update (milliseconds) |
LiquidationPositionByUser
Identical payload to LiquidationPosition, but delivered on the main account's connection instead of the Sub Portfolio's. One connection receives the liquidation position updates for every Sub Portfolio under the main account — use portfolioId to tell them apart.
{
"channel": "LiquidationPositionByUser",
"data": {
"liquidationEventId": "7391234567890001",
"portfolioId": "1702884522340000",
"orderId": "1703213979730000",
"positionId": "1704179813908000",
"exchangeType": "BINANCE",
"sym": "BINANCE_PERP_BTC_USDT",
"positionSide": "LONG",
"reduceQty": "0.05",
"closedPnl": "-5.00",
"markPrice": "50000.00",
"totalTradingFee": "1.25",
"liqFee": "0.50",
"positionMode": "NET",
"leverage": 10,
"uniMmr": "0.52",
"validMargin": "7800.00",
"maintainMargin": "2000.00",
"createAt": 1700000030000,
"updateAt": 1700000030000
}
}Fields are the same as LiquidationPosition above, except channel, which is LiquidationPositionByUser.
