Skip to content

Get Subaccounts

Retrieve all subaccounts under the same master account as the requested subAccountId, plus any subaccounts owned by other wallets that have granted account-level delegation to the caller's wallet. Callable by account owners, subaccount-level delegated signers, and account-level managers authorized for the requested subaccount. Each subaccount includes collateral balances, cross margin summary, positions, market preferences, fee rates, and delegated signers. See Smart Contract Accounts (Safe) for the Gnosis Safe owner + manager workflow.

Endpoint

POST https://papi.synthetix.io/v1/trade

Request

Request Format

{
  "params": {
    "action": "getSubAccounts",
    "subAccountId": "1867542890123456789"
  },
  "expiresAfter": 1735689900,
  "signature": {
    "v": 28,
    "r": "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
    "s": "0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890"
  }
}

Request Parameters

FieldTypeRequiredDescription
paramsobjectYesRequest parameters wrapper
params.actionstringYesMust be "getSubAccounts"
params.subAccountIdstringYesA subaccount the caller can authenticate for (owner, subaccount delegate, or account-level manager). Any ID in the same master account group resolves to the full sibling list. Must match the subAccountId in the EIP-712 SubAccountAction signature.

Top-level Parameters

getSubAccounts uses SubAccountAction signing. These fields sit alongside params at the top level of the request body:

ParameterTypeRequiredDescription
signatureobjectYesEIP-712 signature object (v, r, s)
expiresAfteruint64NoUnix timestamp in seconds (same unit as EIP-712 expiresAfter). Use 0 for no expiration.

nonce is not used on this endpoint.

Optional request header X-Request-ID: when provided, the response echoes it as both requestId and request_id. When omitted, those fields are not included in the response body.

Response

Success Response

The example below includes requestId / request_id because the client sent X-Request-ID.

{
  "status": "ok",
  "response": {
    "subAccounts": [
      {
        "subAccountId": "1867542890123456789",
        "masterAccountId": "1867542890123456788",
        "subAccountName": "Trading Account 1",
        "collaterals": [
          {
            "symbol": "USDC",
            "quantity": "1000.00000000",
            "withdrawable": "1000.00000000",
            "pendingWithdraw": "0.00000000",
            "adjustedCollateralValue": "1000.00",
            "collateralValue": "1000.00",
            "haircutRate": "0",
            "haircutAdjustment": "0.00",
            "price": "1.0000",
            "calculatedAt": 0
          }
        ],
        "crossMarginSummary": {
          "accountValue": "6750.50",
          "availableMargin": "2415.00",
          "totalUnrealizedPnl": "75.00",
          "maintenanceMargin": "1207.50",
          "initialMargin": "2415.00",
          "withdrawable": "4335.50",
          "adjustedAccountValue": "6750.50",
          "debt": "0.00"
        },
        "positions": [],
        "marketPreferences": {
          "leverages": {
            "BTC-USDT": 20
          }
        },
        "feeRates": {
          "makerFeeRate": "0.0002",
          "takerFeeRate": "0.0005",
          "tierName": "Regular User"
        },
        "accountLimits": {
          "maxBorrowCapacity": "10000.00",
          "maxOrdersPerMarket": 10,
          "maxSubAccounts": 10,
          "maxTotalOrders": 100
        },
        "delegatedSigners": [
          {
            "subAccountId": "1867542890123456789",
            "walletAddress": "0x742d35Cc6634C0532925a3b844Bc9e7595f89590",
            "permissions": ["session"],
            "expiresAt": null
          }
        ]
      }
    ],
    "managedAccounts": {
      "0xABcDeF1234567890AbCdEf1234567890AbCdEf12": [
        {
          "subAccountId": "1867542890123456800",
          "masterAccountId": "1867542890123456799",
          "subAccountName": "Managed Trading Account",
          "collaterals": [],
          "crossMarginSummary": {
            "accountValue": "2500.00",
            "availableMargin": "2500.00",
            "totalUnrealizedPnl": "0.00",
            "maintenanceMargin": "0.00",
            "initialMargin": "0.00",
            "withdrawable": "2500.00",
            "adjustedAccountValue": "2500.00",
            "debt": "0.00"
          },
          "positions": [],
          "marketPreferences": { "leverages": {} },
          "feeRates": {
            "makerFeeRate": "0.0002",
            "takerFeeRate": "0.0005",
            "tierName": "Regular User"
          },
          "accountLimits": {
            "maxBorrowCapacity": "10000.00",
            "maxOrdersPerMarket": 10,
            "maxSubAccounts": 10,
            "maxTotalOrders": 100
          },
          "delegatedSigners": []
        }
      ]
    }
  },
  "requestId": "5ccf215d37e3ae6d",
  "request_id": "5ccf215d37e3ae6d",
  "timestamp": 1735689900000
}

Response Fields

FieldTypeDescription
statusstring"ok" on success
responseobjectWrapper containing subAccounts and managedAccounts
response.subAccountsSubAccountWithDelegates[]All subaccounts under the same master account as params.subAccountId (the owner's master tree, regardless of caller role)
response.managedAccountsRecord<WalletAddress, SubAccountWithDelegates[]>Map of owner wallet address to subaccounts the caller manages via account-level delegation. Keys are checksummed hex wallet addresses. Always present; {} when empty. See Smart Contract Accounts (Safe).
requestIdstringOptional. Echo of the X-Request-ID request header (also emitted as legacy request_id). Omitted when the header is not sent.
timestampintegerServer timestamp in milliseconds

SubAccountWithDelegates Object

Each entry in subAccounts and in each managedAccounts value array is a SubAccountWithDelegates object. It includes all standard subaccount fields (flattened) plus a delegatedSigners array:

FieldTypeDescription
subAccountIdstringUnique subaccount identifier
masterAccountIdstring | nullID of the master account (null if this is a master account)
subAccountNamestringHuman-readable subaccount name
collateralsarrayCollateral assets held in this subaccount (see Collateral Object)
crossMarginSummaryobjectAccount value, margins, and P&L (see Cross Margin Summary Object)
positionsarrayOpen positions for this subaccount. For field definitions when non-empty, see Get Positions.
marketPreferencesobjectMarket-specific preferences
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")
feeRates.takerFeeRatestringTaker fee rate as decimal (e.g. "0.0005")
feeRates.tierNamestringFee tier name (e.g. "Regular User", "Top Tier")
accountLimitsobjectAccount limits for this subaccount
accountLimits.maxBorrowCapacitystringMaximum borrow capacity in USD
accountLimits.maxOrdersPerMarketintegerMaximum open orders per market
accountLimits.maxSubAccountsintegerMaximum subaccounts allowed for the master account
accountLimits.maxTotalOrdersintegerMaximum total open orders across all markets

Additional Field

FieldTypeDescription
delegatedSignersDelegatedSigner[]Subaccount-level delegated signers for this subaccount (see below)

Each delegatedSigners entry includes:

FieldTypeDescription
subAccountIdstringSubaccount ID this delegation applies to
walletAddressstringDelegated signer's wallet address
permissionsstring[]Permission levels granted. Canonical values are session and delegate; legacy records may return trading (equivalent to session).
expiresAtinteger | nullExpiration timestamp in milliseconds, or null if no expiration

addedBy is not returned on this endpoint. For the full delegation record including addedBy, use Get Delegated Signers.

managedAccounts Map

The managedAccounts field is a JSON object (map) where:

  • Keys are owner wallet addresses (string, EIP-55 checksummed) of accounts that granted account-level delegation to the caller
  • Values are arrays of SubAccountWithDelegates objects owned by that wallet

An empty object ({}) is returned when no managed accounts exist.

Collateral Object

FieldTypeDescription
symbolstringCollateral token symbol (e.g., "USDT")
quantitystringAmount of collateral held
withdrawablestringAmount available for withdrawal
pendingWithdrawstringAmount pending withdrawal
adjustedCollateralValuestringCollateral value after applying haircut discount (USD equivalent)
collateralValuestringFull collateral value before haircut (USD equivalent)
haircutRatestringHaircut rate applied to this collateral (e.g., "0.1" = 10% discount)
haircutAdjustmentstringAbsolute haircut adjustment amount in USD
pricestringCollateral token price in USD at time of calculation
calculatedAtintegerUnix timestamp (milliseconds) when price was last calculated; 0 for USDT

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
debtstringOutstanding debt in the account

Error Response

Shown with X-Request-ID sent (same echo rules as success).

{
  "status": "error",
  "error": {
    "message": "subaccountId is required",
    "code": "VALIDATION_ERROR"
  },
  "requestId": "5ccf215d37e3ae6d",
  "request_id": "5ccf215d37e3ae6d",
  "timestamp": 1735689900000
}
Error CodeDescriptionRetryable
UNAUTHORIZEDEIP-712 signature validation failedNo
VALIDATION_ERRORRequest validation failedNo
MISSING_REQUIRED_FIELDRequired field is missingNo
INVALID_FORMATField format is invalidNo
INVALID_VALUEInvalid parameter valueNo
RATE_LIMIT_EXCEEDEDToo many requests in time windowYes
INSUFFICIENT_MARGINNot enough margin for tradeNo
ORDER_NOT_FOUNDOrder does not existNo
OPERATION_TIMEOUTOperation timed outYes
ErrorHTTPCodeDescription
subaccountId is required400VALIDATION_ERRORparams.subAccountId missing or not resolved from auth context
Invalid subaccountId: must be a valid number400VALIDATION_ERRORparams.subAccountId is not a non-negative integer string
authentication failed: … wallet … is not authorized to act on this subaccount401UNAUTHORIZEDSigner lacks owner, delegate, or manager access to the requested subAccountId, or the subAccountId does not exist (auth runs before list lookup)
Failed to list subaccounts500INTERNAL_ERRORSubaccount service error after auth succeeds

Subaccount Information

  • Account Access: Caller must be the subaccount owner, a subaccount-level delegated signer, or an account-level manager authorized for the requested subAccountId
  • Pure managers: Use getSubAccountIds with includeDelegations: true to discover managedSubAccountIds, then sign this call with one of those IDs
  • subAccounts: Always lists all subaccounts under the same master account as params.subAccountId (the owner's master tree, not filtered by caller wallet). A non-existent subAccountId returns 401 / UNAUTHORIZED at auth, not an empty list
  • subAccounts vs managedAccounts: For a single Safe, these overlap; managedAccounts additionally lists every owner workspace when the caller manages multiple accounts
  • Managed Accounts: managedAccounts is populated when the authenticated wallet has account-level delegation granted by other wallet owners; it is an empty map ({}) when no such delegations exist
  • Delegation Visibility: Includes delegatedSigners for each subaccount, unlike getSubAccount
  • Complementary Data: Use with getPositions for detailed position information and getPerformanceHistory for performance analytics

Code Examples

EIP-712 Signature

const domain = {
  name: "Synthetix",
  version: "1",
  chainId: 1,
  verifyingContract: "0x0000000000000000000000000000000000000000"
};
 
const types = {
  SubAccountAction: [
    { name: "subAccountId", type: "uint256" },
    { name: "action", type: "string" },
    { name: "expiresAfter", type: "uint256" }
  ]
};
 
const message = {
  subAccountId: "1867542890123456789",
  action: "getSubAccounts",
  expiresAfter: 0  // Optional, use 0 for no expiration
};
 
const signature = await signer._signTypedData(domain, types, message);

Comparison with getSubAccount

FeaturegetSubAccountgetSubAccounts
ReturnsSingle subaccountMaster-tree siblings (subAccounts) under the same master as authenticated subAccountId, plus managed accounts map (managedAccounts)
Response shapeSingle objectWrapper with subAccounts + managedAccounts
Delegated SignersNot includedIncluded for each subaccount
Managed AccountsNot includedIncluded in managedAccounts map
Use CaseSpecific account lookupFull account overview with delegation info

Related Endpoints

:::info Rate Limits The Synthetix API enforces rate limits to ensure fair usage and system stability:

  • Order Placement: 100 orders per second per subaccount
  • WebSocket Connections: 100 connections per IP address
  • WebSocket Subscriptions: 1000 subscriptions per IP address

See Rate Limits for detailed information and best practices. :::

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.