Skip to main content
An ETF vault’s holdings are split into separate balances for fund assets, network fees, and (for staking ETFs) spam. The wallet endpoints report what each wallet holds, not this split. To report on each balance and its transactions on its own, use the subaccount endpoints in the v2 API.

ETF balances in the API

The API calls each ETF balance a subaccount. A subaccount is an entry in our ledger, not a wallet or a place on-chain. The wallets show where assets are held. The subaccounts show what those assets represent. The subaccounts are peers under your organization. They aren’t nested, and none of them replaces your vaults and wallets. For how the balances relate to the wallet structure, see the ETF overview.

Set up

You need an API key with the Read sub-accounts permission. See Permission groups for how to assign it. These endpoints are read-only for ETF reporting. You don’t create or change subaccounts. The examples use the sandbox base URL. For production, see Base URLs.

Step 1: List your ETF balances

GET /v2/subaccounts/customers/accounts Lists the subaccounts for your organization, each with its current balances per asset. See List all subaccounts for the full reference.
Request
Response (trimmed)
Where:
  • subaccountId is the ID to use when you pull transactions for that balance. Store it.
  • name identifies the balance. A staking ETF returns a spam balance in addition to the fund and network fee balances. Other ETFs don’t.
  • balances has one entry per asset, with totalBalance, availableForWithdrawal, and availableForTrading.
Narrow the list with these query parameters: To fetch the next page, request the page.next URL from the previous response. A null page.next means there are no more results. See Pagination.

Step 2: List transactions for a balance

GET /v2/subaccounts/transactions Lists transactions, newest activity first by creation date. Pass subaccountId to see one balance. Use the ID from step 1 for your fund, network fee, or spam balance. See List all transactions for the full reference.
Request
Response (trimmed)
Where:
  • transactionType is one of the types in the reference, such as DEPOSIT, WITHDRAWAL, GAS_FILL, or TRANSACTION_FEE.
  • status is POSTED, PENDING, or CANCELED. A PENDING transaction holds funds until it posts or is canceled.
  • subaccounts lists the balances the transaction touched, each with amounts per asset and balanceType.
  • endedAt is set once the transaction reaches POSTED or CANCELED.
Filter the list with these query parameters: To fetch specific transactions, use GET /v2/subaccounts/transactions/{transactionsIds} with one or more comma-separated transaction IDs. It accepts the same date and pagination parameters.

Reconcile each balance

To reconcile a day or a month, combine the two calls:
  1. Call GET /v2/subaccounts/customers/accounts and record each balance’s totalBalance per asset.
  2. Call GET /v2/subaccounts/transactions once per subaccountId with startDate and endDate, and follow page.next until it’s null.
  3. Compare the balances against the transactions, one balance at a time.
Wallet-level reporting stays available alongside this. Use GET /v2/wallets and GET /v2/transactions for what each wallet holds and moves on-chain, as described in the Reporting overview. Your monthly custody statements cover the fund balance only. Use the subaccount endpoints when you also need the network fee and spam balances.