Returns real-time per-asset token balances and USD values for a portfolio.
totalValueUsd. Balances are
read fresh per call from the indexer and chain RPC fallback, then cached
upstream for 30 seconds so rapid polling from a single caller is cheap. For
pure DB reads (schedule status, strategy metadata, vault addresses) use
GET /v2/portfolios/{portfolioId} instead — it is significantly cheaper and
safe to poll.
x-api-key header (required)portfolios:read200 with whatever
loaded and a structured warnings[] array describing the gap. A full failure
returns totalValueUsd: "0", assets: [], and populated warnings — never
a 5xx for upstream degradation. 5xx is reserved for unhandled server
exceptions or a deployment where the live-value service is not wired.
Multi-chain by construction. Every asset entry carries a full CAIP-19
assetId and a CAIP-10 vaultAccountId, so EVM and non-EVM holdings share
one wire shape. B2B enrollment today only creates EVM vaults, but when
Solana or another chain is added, the response format does not need to
change — only the values inside the CAIP strings.
POST /v2/enroll or GET /v2/portfolios.400 when the path parameter is invalid401 when x-api-key header is missing or the key is invalid403 when the API key lacks the portfolios:read scope404 when the portfolio does not exist or does not belong to the tenant500 on unexpected server errors or when live-balance service is unavailablewarnings[]):
MISSING_VAULT — indexer has no vault record for the requested chainRPC_ERROR — chain RPC timed out or erroredMISSING_PRICE — no USD price found for an assetBLOCKLISTED_ASSET — asset is on the runtime blocklist and was skippedMISSING_ASSET — asset metadata missing from the indexer