Subscribe
Single Account
{
"method" : "subscribe" ,
"subscription" : [{
"type" : "account" ,
"user" : "FuueqefENiGEW6uMqZQgmwjzgpnb85EgUcZa5Em4PQh7"
}]
}
Multiple Accounts (Batched)
Subscribe to multiple accounts in a single request:
{
"method" : "subscribe" ,
"subscription" : [{
"type" : "account" ,
"user" : [
"FuueqefENiGEW6uMqZQgmwjzgpnb85EgUcZa5Em4PQh7" ,
"5Am6JkEHAjYG1itNWRMGpQrxvY8AaqkXCo1TZvenqVux" ,
"9J8TUdEWrrcADK913r1Cs7DdqX63VdVU88imfDzT1ypt"
]
}]
}
Response
{
"type" : "subscriptionResponse" ,
"topics" : [
"account.FuueqefENiGEW6uMqZQgmwjzgpnb85EgUcZa5Em4PQh7" ,
"account.5Am6JkEHAjYG1itNWRMGpQrxvY8AaqkXCo1TZvenqVux" ,
"account.9J8TUdEWrrcADK913r1Cs7DdqX63VdVU88imfDzT1ypt"
]
}
Parameters:
user (String or Array): User public key(s) in base58 format
Single: "user": "9J8T..."
Multiple: "user": ["9J8T...", "5Am6...", "ABC..."]
Initial Snapshot
On subscription, you receive a unified accountSnapshot message with complete account state:
{
"type" : "account" ,
"data" : {
"type" : "accountSnapshot" ,
"margin" : {
"totalBalance" : 100000.0 ,
"availableBalance" : 95000.0 ,
"marginUsed" : 5000.0 ,
"notional" : 50000.0 ,
"realizedPnl" : 1234.5 ,
"unrealizedPnl" : 567.8 ,
"fees" : 12.34 ,
"funding" : 5.67
},
"positions" : [
{
"symbol" : "BTC-USD" ,
"size" : 0.5 ,
"price" : 100000.0 ,
"fairPrice" : 101000.0 ,
"notional" : 50500.0 ,
"realizedPnl" : 500.0 ,
"unrealizedPnl" : 500.0 ,
"leverage" : 5.0 ,
"liquidationPrice" : 95000.0 ,
"fees" : 10.0 ,
"funding" : 2.5 ,
"maintenanceMargin" : 1000.0 ,
"lambda" : 0.05 ,
"riskAllocation" : 5000.0 ,
"allocMargin" : 2500.0
}
],
"openOrders" : [
{
"symbol" : "BTC-USD" ,
"orderId" : "Fpa3oVuL3UzjNANAMZZdmrn6D1Zhk83GmBuJpuAWG51F" ,
"price" : 102000.0 ,
"originalSize" : 0.1 ,
"size" : 0.1 ,
"filledSize" : 0.0 ,
"vwap" : 0.0 ,
"isBuy" : true ,
"maker" : true ,
"reduceOnly" : false ,
"tif" : "gtc" ,
"status" : "placed" ,
"timestamp" : 1763316177219383423
}
],
"leverageSettings" : [
{ "symbol" : "BTC-USD" , "leverage" : 5.0 },
{ "symbol" : "ETH-USD" , "leverage" : 3.0 }
]
},
"topic" : "account.FuueqefENiGEW6uMqZQgmwjzgpnb85EgUcZa5Em4PQh7"
}
Account Snapshot Fields
Margin:
Field Description totalBalanceTotal margin balance availableBalanceAvailable margin (total - maintenance margin) marginUsedMaintenance margin used notionalTotal notional value of all positions realizedPnlRealized profit/loss unrealizedPnlUnrealized profit/loss feesTotal fees paid fundingTotal funding paid/received
Positions:
Field Description symbolMarket symbol sizePosition size (positive=long, negative=short) priceVWAP entry price fairPriceCurrent fair/mark price notionalNotional value (size × fair_price) realizedPnlRealized P&L for this position unrealizedPnlUnrealized P&L for this position leveragePosition leverage liquidationPriceLiquidation price feesFees paid for this position fundingFunding paid/received maintenanceMarginRequired maintenance margin lambdaLambda (risk parameter) riskAllocationRisk allocation (C_i) allocMarginAllocated margin for this position
Open Orders:
Field Description symbolMarket symbol orderIdOrder ID (base58, use for cancellation) priceOrder price originalSizeOriginal order size sizeCurrent remaining size filledSizeFilled size vwapVWAP fill price (0 if no fills) isBuytrue for buy, false for sellmakertrue if maker orderreduceOnlytrue if reduce-onlytifTime in force (gtc, ioc, postOnly) statusOrder status (placed, working, etc.) timestampOrder placement time (nanoseconds)
Leverage Settings (included in initial snapshot only):
Field Description symbolMarket symbol leverageMaximum leverage (1.0 to 50.0)
Real-time Delta Updates
After the initial snapshot, you receive delta updates for changes:
Margin Update
{
"type" : "account" ,
"data" : {
"type" : "marginUpdate" ,
"totalBalance" : 100500.0 ,
"availableBalance" : 95500.0 ,
"marginUsed" : 5000.0 ,
"notional" : 50500.0 ,
"realizedPnl" : 1234.5 ,
"unrealizedPnl" : 567.8 ,
"fees" : 12.34 ,
"funding" : 5.67
},
"topic" : "account.FuueqefENiGEW6uMqZQgmwjzgpnb85EgUcZa5Em4PQh7"
}
Position Update
{
"type" : "account" ,
"data" : {
"type" : "positionUpdate" ,
"symbol" : "BTC-USD" ,
"size" : 0.5 ,
"price" : 100000.0 ,
"realizedPnl" : 500.0 ,
"unrealizedPnl" : 500.0 ,
"leverage" : 5.0 ,
"liquidationPrice" : 95000.0 ,
"fairPrice" : 101000.0 ,
"notional" : 50500.0 ,
"fees" : 10.0 ,
"funding" : 2.5 ,
"maintenanceMargin" : 1000.0 ,
"lambda" : 0.05 ,
"riskAllocation" : 5000.0 ,
"allocMargin" : 2500.0
},
"topic" : "account.FuueqefENiGEW6uMqZQgmwjzgpnb85EgUcZa5Em4PQh7"
}
Order Update
All order state changes are delivered via unified orderUpdate messages with full state information.
{
"type" : "account" ,
"data" : {
"type" : "orderUpdate" ,
"status" : "placed" ,
"symbol" : "BTC-USD" ,
"orderId" : "Fpa3oVuL3UzjNANAMZZdmrn6D1Zhk83GmBuJpuAWG51F" ,
"price" : 102000.0 ,
"originalSize" : 0.1 ,
"size" : 0.1 ,
"filledSize" : 0.0 ,
"vwap" : 0.0 ,
"isBuy" : true ,
"maker" : true ,
"timestamp" : 1763316177219383423 ,
"reason" : null
},
"topic" : "account.FuueqefENiGEW6uMqZQgmwjzgpnb85EgUcZa5Em4PQh7"
}
Order Update Fields
Field Description statusOrder status (see table below) symbolMarket symbol orderIdOrder ID (base58) priceOrder price originalSizeOriginal order size sizeCurrent remaining size filledSizeAmount filled vwapVWAP fill price isBuytrue for buy ordersmakertrue if maker ordertimestampOrder timestamp (nanoseconds) reasonRejection/cancellation reason (optional)
Order Status Values
Status Terminal Description placedNo Order placed and resting on book workingNo Order has partial fills, still resting filledYes Order fully filled partiallyFilledYes Order partially filled and terminal cancelledYes Order cancelled by user cancelledRiskLimitYes Cancelled due to risk limit cancelledSelfCrossingYes Cancelled due to self-crossing (STP) cancelledReduceOnlyYes Cancelled - would not reduce position cancelledIOCYes IOC expired without full fill rejectedCrossingYes Post-only rejected for crossing rejectedDuplicateYes Duplicate order ID rejectedRiskLimitYes Rejected due to risk limit rejectedInvalidYes Invalid order parameters
Order Update Examples
Order Placed (resting)
Order Working (partial fill, still resting)
Order Filled
Order Cancelled (user)
Cancelled Risk Limit
Post-Only Rejected
{
"type" : "account" ,
"data" : {
"type" : "orderUpdate" ,
"status" : "placed" ,
"symbol" : "BTC-USD" ,
"orderId" : "Fpa3oVuL3UzjNANAMZZdmrn6D1Zhk83GmBuJpuAWG51F" ,
"price" : 100000.0 ,
"originalSize" : 0.1 ,
"size" : 0.1 ,
"filledSize" : 0.0 ,
"vwap" : 0.0 ,
"isBuy" : true ,
"maker" : true ,
"timestamp" : 1763316177219383423 ,
"reason" : null
},
"topic" : "account.FuueqefENiGEW6uMqZQgmwjzgpnb85EgUcZa5Em4PQh7"
}
Legacy order messages: For backwards compatibility, order messages with status: "placed" or status: "cancelled" may still be emitted alongside orderUpdate. New integrations should use orderUpdate messages exclusively.
Fill Update
Emitted on each trade execution (in addition to orderUpdate):
{
"type" : "account" ,
"data" : {
"type" : "fill" ,
"symbol" : "BTC-USD" ,
"orderId" : "Fpa3oVuL3UzjNANAMZZdmrn6D1Zhk83GmBuJpuAWG51F" ,
"price" : 102000.0 ,
"size" : 0.05 ,
"isBuy" : true ,
"timestamp" : 1763316177219383423 ,
"maker" : false
},
"topic" : "account.FuueqefENiGEW6uMqZQgmwjzgpnb85EgUcZa5Em4PQh7"
}
Liquidation Event
Emitted when the account is liquidated:
{
"type" : "account" ,
"data" : {
"type" : "liquidation" ,
"symbol" : "BTC-USD" ,
"price" : 95000.0 ,
"size" : 0.5 ,
"isBuy" : false ,
"marginPrior" : 5000.0 ,
"marginAfter" : 0.0 ,
"timestamp" : 1763316177219383423
},
"topic" : "account.FuueqefENiGEW6uMqZQgmwjzgpnb85EgUcZa5Em4PQh7"
}
Field Description symbolMarket symbol priceLiquidation price sizePosition size that was liquidated isBuyDirection of the liquidation fill marginPriorMargin balance before liquidation marginAfterMargin balance after liquidation timestampTimestamp (nanoseconds)
ADL (Auto-Deleveraging) Event
Emitted when the account is auto-deleveraged:
{
"type" : "account" ,
"data" : {
"type" : "ADL" ,
"symbol" : "BTC-USD" ,
"price" : 95000.0 ,
"size" : 0.5 ,
"isBuy" : false ,
"timestamp" : 1763316177219383423
},
"topic" : "account.FuueqefENiGEW6uMqZQgmwjzgpnb85EgUcZa5Em4PQh7"
}
Field Description symbolMarket symbol priceADL price sizePosition size that was auto-deleveraged isBuyDirection of the ADL fill timestampTimestamp (nanoseconds)
Cancel Rejected
Emitted when a single-order cancel is rejected (e.g. order not found):
{
"type" : "account" ,
"data" : {
"type" : "cancelOneRejected" ,
"symbol" : "BTC-USD" ,
"orderId" : "Fpa3oVuL3UzjNANAMZZdmrn6D1Zhk83GmBuJpuAWG51F" ,
"reason" : "Order not found" ,
"timestamp" : 1763316177219383423
},
"topic" : "account.FuueqefENiGEW6uMqZQgmwjzgpnb85EgUcZa5Em4PQh7"
}
Cancel All Rejected
Emitted when cancel-all is rejected (e.g. no open orders):
{
"type" : "account" ,
"data" : {
"type" : "cancelAllRejected" ,
"symbol" : "BTC-USD" ,
"reason" : "No open orders" ,
"timestamp" : 1763316177219383423
},
"topic" : "account.FuueqefENiGEW6uMqZQgmwjzgpnb85EgUcZa5Em4PQh7"
}
Leverage Update
{
"type" : "account" ,
"data" : {
"type" : "leverageUpdate" ,
"leverage" : [
{ "symbol" : "BTC-USD" , "leverage" : 5.0 }
]
},
"topic" : "account.FuueqefENiGEW6uMqZQgmwjzgpnb85EgUcZa5Em4PQh7"
}
Update Frequency
Initial Snapshot : Sent immediately on subscription (single unified accountSnapshot message).
Event-driven : Margin, positions, and leverage settings are sent when they change.
Real-time : Immediately on all order state changes (orderUpdate), including:
Order placement (placed, resting)
Partial fills (working)
Full fills (filled)
Cancellations (cancelled, cancelledRiskLimit, cancelledIOC, etc.)
Rejections (rejectedCrossing, rejectedRiskLimit, etc.)
Example: Monitor Account
const WebSocket = require ( 'ws' );
const PUBLIC_KEY = 'FuueqefENiGEW6uMqZQgmwjzgpnb85EgUcZa5Em4PQh7' ;
const ws = new WebSocket ( 'wss://exchange-ws1.bulk.trade' );
ws . on ( 'open' , () => {
console . log ( 'Connected' );
// Subscribe to account updates
ws . send ( JSON . stringify ({
method: 'subscribe' ,
subscription: [{
type: 'account' ,
user: PUBLIC_KEY
}]
}));
});
ws . on ( 'message' , ( data ) => {
const message = JSON . parse ( data );
if ( message . type === 'subscriptionResponse' ) {
console . log ( 'Subscribed to:' , message . topics );
return ;
}
if ( message . type === 'account' ) {
const { type , ... details } = message . data ;
switch ( type ) {
case 'accountSnapshot' :
console . log ( 'Account snapshot:' , details );
console . log ( 'Positions:' , details . positions );
console . log ( 'Open orders:' , details . openOrders );
break ;
case 'marginUpdate' :
console . log ( 'Margin update:' , details );
break ;
case 'positionUpdate' :
console . log ( 'Position update:' , details );
break ;
case 'orderUpdate' :
console . log ( `Order ${ details . status } :` , details );
break ;
case 'fill' :
console . log ( 'Fill:' , details );
break ;
case 'leverageUpdate' :
console . log ( 'Leverage updated:' , details );
break ;
case 'liquidation' :
console . log ( 'Liquidation:' , details );
break ;
case 'ADL' :
console . log ( 'ADL:' , details );
break ;
case 'cancelOneRejected' :
console . log ( 'Cancel rejected:' , details );
break ;
case 'cancelAllRejected' :
console . log ( 'Cancel all rejected:' , details );
break ;
}
}
});
Unsubscribe
{
"method" : "unsubscribe" ,
"topic" : "account.FuueqefENiGEW6uMqZQgmwjzgpnb85EgUcZa5Em4PQh7"
}