Skip to content

Get Subaccounts (WebSocket)

Retrieve a list of subaccounts (including delegated subaccounts) for the signing wallet address through the WebSocket connection, providing essential account metadata, collateral information, and cross margin summaries for account selection and management.

Endpoint

ws.send() wss://api.synthetix.io/v1/ws/trade

Request

Request Format

{
  "id": "subaccounts-1",
  "method": "post",
  "params": {
    "action": "getSubaccounts",
    "nonce": 1735689600000,
    "signature": {
      "v": 28,
      "r": "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
      "s": "0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890"
    }
  }
}

Request Parameters

ParameterTypeRequiredDescription
idstringYesClient-generated unique request identifier
methodstringYesMust be "post"
paramsobjectYesRequest parameters wrapper
params.actionstringYesMust be "getSubaccounts"
params.nonceintegerYesCurrent timestamp in milliseconds
params.signatureobjectYesEIP-712 signature of the request
ParameterTypeRequiredDescription
nonceuint64YesUnix milliseconds timestamp (must be monotonically increasing)
signatureobjectYesEIP-712 signature object
expiresAfteruint64NoUnix milliseconds expiration timestamp (5x rate limit on stale cancels)

:::info Common Parameters These are top-level request parameters. The subAccountId parameter is specified within the params object (see each endpoint's parameter table). :::

Response

Success Response

{
  "id": "subaccounts-1",
  "status": 200,
  "result": [
    {
      "subAccountId": "1867542890123456789",
      "masterAccountId": "1867542890123456788",
      "subAccountName": "Trading Account 1",
      "collaterals": [
        {
          "symbol": "USDT",
          "quantity": "1000.00000000"
        },
        {
          "symbol": "ETH",
          "quantity": "0.5000"
        }
      ],
      "crossMarginSummary": {
        "accountValue": "6750.50",
        "availableMargin": "2415.00",
        "totalUnrealizedPnl": "75.00",
        "maintenanceMargin": "1207.50",
        "initialMargin": "2415.00",
        "withdrawable": "4335.50",
        "adjustedAccountValue": "6750.50"
      },
      "positions": [],
      "marketPreferences": {
        "leverages": {
          "BTC-USDT": 20,
          "ETH-USDT": 10
        }
      }
    },
    {
      "subAccountId": "1867542890123456790",
      "masterAccountId": null,
      "subAccountName": "Trading Account 2",
      "collaterals": [],
      "crossMarginSummary": {
        "accountValue": "0.00",
        "availableMargin": "0.00",
        "totalUnrealizedPnl": "0.00",
        "maintenanceMargin": "0.00",
        "initialMargin": "0.00",
        "withdrawable": "0.00",
        "adjustedAccountValue": "0.00"
      },
      "positions": [],
      "marketPreferences": {
        "leverages": {}
      }
    }
  ]
}

Subaccount Object

FieldTypeDescription
subAccountIdstringUnique subaccount identifier
masterAccountIdstring | nullID of the master account (null if this is a master account)
subAccountNamestringHuman-readable subaccount name
collateralsarrayArray of collateral assets held in this subaccount
crossMarginSummaryobjectCross margin summary with account value, margins, and P&L
positionsarrayArray of open positions for this subaccount
marketPreferencesobjectMarket-specific preferences and settings
marketPreferences.leveragesobjectPer-market leverage settings (key: symbol, value: leverage multiplier)
feeRatesobjectFee rate information for this subaccount
feeRates.makerFeeRatestringMaker fee rate as decimal (e.g., "0.0002" for 0.02%)
feeRates.takerFeeRatestringTaker fee rate as decimal (e.g., "0.0005" for 0.05%)
feeRates.tierNamestringFee tier name (e.g., "Regular User", "Tier 1")

Collateral Object

FieldTypeDescription
symbolstringCollateral token symbol (e.g., "USDT")
quantitystringAmount of collateral held

Cross Margin Summary Object

FieldTypeDescription
accountValuestringTotal account value including PnL
availableMarginstringUSDT amount available for new positions
totalUnrealizedPnlstringSum of all unrealized PnL
maintenanceMarginstringMinimum margin required for all positions
initialMarginstringInitial margin required for all positions
withdrawablestringUSDT amount available for withdrawal
adjustedAccountValuestringAdjusted account value for margin calculations

Error Response

{
  "id": "subaccounts-1",
  "status": 500,
  "result": null,
  "error": {
    "code": 500,
    "message": "Failed to list subaccounts"
  }
}
ErrorDescription
Invalid signatureEIP-712 signature validation failed
Invalid market symbolMarket symbol not recognized
Nonce already usedNonce must be greater than previous value
Rate limit exceededToo many requests in time window
Request expiredexpiresAfter timestamp has passed

WebSocket Connection Example

const ethers = require('ethers');
const WebSocket = require('ws');
 
async function getSubaccounts(wallet) {
  const ws = new WebSocket('wss://papi.synthetix.io/v1/ws/trade');
  
  await new Promise((resolve) => {
    ws.on('open', resolve);
  });
 
  // Authenticate first
  const authTimestamp = Date.now();
  const authDomain = {
    name: 'Synthetix',
    version: '1',
    chainId: 1,
    verifyingContract: '0x0000000000000000000000000000000000000000'
  };
  
  const authTypes = {
    Authenticate: [
      { name: 'timestamp', type: 'uint256' }
    ]
  };
  
  const authMessage = { timestamp: authTimestamp };
  const authSignature = await wallet._signTypedData(authDomain, authTypes, authMessage);
  
  ws.send(JSON.stringify({
    id: 'auth-1',
    method: 'auth',
    params: {
      message: JSON.stringify(authMessage),
      signature: authSignature
    }
  }));
 
  // Wait for auth response
  await new Promise((resolve) => {
    ws.once('message', (data) => {
      const response = JSON.parse(data);
      if (response.id === 'auth-1') {
        console.log('Authenticated');
        resolve();
      }
    });
  });
 
  // Now request subaccounts
  const nonce = Date.now();
  const domain = {
    name: 'Synthetix',
    version: '1',
    chainId: 1,
    verifyingContract: '0x0000000000000000000000000000000000000000'
  };
 
  const types = {
    GetSubaccounts: [
      { name: 'action', type: 'string' },
      { name: 'nonce', type: 'uint256' }
    ]
  };
 
  const message = {
    action: 'getSubaccounts',
    nonce
  };
 
  const signature = await wallet._signTypedData(domain, types, message);
  const sig = ethers.utils.splitSignature(signature);
 
  ws.send(JSON.stringify({
    id: 'subaccounts-1',
    method: 'post',
    params: {
      action: 'getSubaccounts',
      nonce,
      signature: {
        v: sig.v,
        r: sig.r,
        s: sig.s
      }
    }
  }));
 
  // Handle response
  return new Promise((resolve) => {
    ws.on('message', (data) => {
      const response = JSON.parse(data);
      if (response.id === 'subaccounts-1') {
        if (response.status === 200) {
          console.log('Subaccounts:', response.result);
          resolve(response.result);
        } else {
          console.error('Error:', response.error);
          resolve(null);
        }
        ws.close();
      }
    });
  });
}
 
// Usage
const wallet = new ethers.Wallet('YOUR_PRIVATE_KEY');
getSubaccounts(wallet);

Subaccount Information

  • Multiple Accounts: Users can have multiple subaccounts for different trading strategies
  • Shared Wallet: All subaccounts share the same underlying wallet address
  • Account Metadata: Provides essential account information for selection and identification
  • Collateral Overview: Shows which assets are held in each subaccount for informed selection
  • Master Account Relationships: Subaccounts can identify their master account hierarchy
  • Account Selection: Designed for building account switchers and management interfaces
  • Focused Data: Includes collateral and cross margin summary for informed account selection
  • Margin Overview: Provides comprehensive margin and balance data across all positions for each subaccount
  • Complementary Data: Use with getPositions for position details

Use Cases

  • Account Management: Build account switcher interfaces
  • Portfolio Overview: Display account balances and collateral
  • Risk Monitoring: Monitor margin usage across accounts
  • Trading Interface: Enable multi-account trading strategies
  • Delegation Management: View delegated subaccount access

Signing

All trading methods are signed using EIP-712. Each successful trading request will contain:

  • A piece of structured data that includes the sender address
  • A signature of the hash of that structured data, signed by the sender

For detailed information on EIP-712 signing, see EIP-712 Signing.

{
  "v": 28,
  "r": "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
  "s": "0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890"
}

Nonce Management

The nonce system prevents replay attacks and ensures order uniqueness:

  • Use current timestamp in milliseconds as nonce
  • Each nonce must be greater than the previous one
  • Recommended: Use Date.now() or equivalent
  • If nonce conflicts occur, increment by 1 and retry

Related Endpoints