Portfolio
Access complete onchain portfolio data with a single query. The portfolio query provides comprehensive access to balances across tokens, apps, and NFTs, along with detailed portfolio totals and breakdowns.
Overview
The portfolio
query takes an array of addresses
as input, with optional parameters for networks
, appIds
, and withOverrides
. It returns a complete view of onchain holdings including:
Portfolio Fields
1. Token Balances (tokenBalances
)
Access native token holdings across different networks with real-time computation built in.
Token balances are now available through the new portfolioV2
query. This updated endpoint eliminates the need for separate balance computation jobs and provides enhanced functionality. The original portfolio
query will continue to work but we recommend migrating to portfolioV2
for token balances.
Example Variables
{
"addresses": ["0x849151d7d0bf1f34b70d5cad5149d28cc2308bf1"],
"first": 5
}
Example Query
query TokenBalances($addresses: [Address!]!, $first: Int) {
portfolioV2(addresses: $addresses) {
tokenBalances {
totalBalanceUSD
byToken(first: $first) {
totalCount
edges {
node {
symbol
tokenAddress
balance
balanceUSD
price
imgUrlV2
name
network {
name
}
}
}
}
}
}
}
Example Response
{
"data": {
"portfolioV2": {
"tokenBalances": {
"totalBalanceUSD": 292328.8286857288,
"byToken": {
"totalCount": 1223,
"edges": [
{
"node": {
"symbol": "ETH",
"tokenAddress": "0x0000000000000000000000000000000000000000",
"balance": 17.286417826281596,
"balanceUSD": 45317.035788310255,
"price": 2621.54,
"imgUrlV2": "https://storage.googleapis.com/zapper-fi-assets/tokens/base/0x0000000000000000000000000000000000000000.png",
"name": "Ethereum",
"network": {
"name": "Base"
}
}
},
{
"node": {
"symbol": "SYNDOG",
"tokenAddress": "0x3d1d651761d535df881740ab50ba4bd8a2ec2c00",
"balance": 30000000,
"balanceUSD": 38615.1,
"price": 0.00128717,
"imgUrlV2": "https://storage.googleapis.com/zapper-fi-assets/tokens/base/0x3d1d651761d535df881740ab50ba4bd8a2ec2c00.png",
"name": "Synthesizer Dog",
"network": {
"name": "Base"
}
}
},
{
"node": {
"symbol": "BKIT",
"tokenAddress": "0x262a9f4e84efa2816d87a68606bb4c1ea3874bf1",
"balance": 28980487535.238518,
"balanceUSD": 28654.60195290476,
"price": 9.88755e-7,
"imgUrlV2": "https://storage.googleapis.com/zapper-fi-assets/tokens/base/0x262a9f4e84efa2816d87a68606bb4c1ea3874bf1.png",
"name": "Bangkit",
"network": {
"name": "Base"
}
}
},
{
"node": {
"symbol": "ERA",
"tokenAddress": "0xb82d1d9dd2ca8cfbdecdfbfef0aaebb07eb29312",
"balance": 50408655.54694379,
"balanceUSD": 13756.164212247695,
"price": 0.0002728929002963999,
"imgUrlV2": "https://storage.googleapis.com/zapper-fi-assets/tokens/base/0xb82d1d9dd2ca8cfbdecdfbfef0aaebb07eb29312.png",
"name": "BASE ERA",
"network": {
"name": "Base"
}
}
},
{
"node": {
"symbol": "BNKR",
"tokenAddress": "0x22af33fe49fd1fa80c7149773dde5890d3c76f3b",
"balance": 55169518.28804873,
"balanceUSD": 10414.901662417838,
"price": 0.00018878,
"imgUrlV2": "https://storage.googleapis.com/zapper-fi-assets/tokens/base/0x22af33fe49fd1fa80c7149773dde5890d3c76f3b.png",
"name": "BankrCoin",
"network": {
"name": "Base"
}
}
}
]
}
}
}
}
}
Key Features
- Real-time Computation: No separate computation jobs needed
- Flexible Querying: View balances by token, account, or network
- Detailed Token Data: Complete token metadata and balances
- Account-level Breakdown: See individual wallet contributions to total balances
Available Fields
Token Balance Root Fields
Field | Description | Type |
---|---|---|
totalBalanceUSD | Total portfolio value in USD | Float! |
byToken | Token-centric view of balances | PortfolioV2TokenBalanceByTokenConnection! |
byAccount | Account-centric view of balances | PortfolioV2TokenBalancesByAccountConnection! |
byNetwork | Network-centric view of balances | PortfolioV2TokenBalancesByNetworkConnection! |
Token Balance Node Fields
Field | Description | Type |
---|---|---|
tokenAddress | Token contract address | String! |
networkId | Network identifier | ID! |
name | Token name | String! |
symbol | Token symbol | String! |
decimals | Token decimal places | Float! |
price | Current token price | Float! |
balance | Total balance across all accounts | Float! |
balanceUSD | USD value of total balance | Float! |
balanceRaw | Raw balance amount (pre-decimal adjustment) | String! |
network | Detailed network information | NetworkObject! |
imgUrl | Token icon URL (deprecated) | String! |
imgUrlV2 | Token icon URL (null if not found) | String |
Account Balance Fields
Field | Description | Type |
---|---|---|
accountAddress | Wallet address | Address! |
balance | Token balance for this account | Float! |
balanceUSD | USD value for this account | Float! |
balanceRaw | Raw balance for this account | String! |
account | Detailed account information | Account! |
Filtering Options
The byToken
query accepts several filtering parameters:
byToken(
first: Int = 25,
after: String,
filters: {
minBalanceUSD: Float
symbolLike: String
tokenAddress: String
includeTokensWithMissingPrices: Boolean
}
)
Similar filtering options are available for byAccount
and byNetwork
queries.
When working with raw balances, remember to adjust for token decimals. For example, a balanceRaw
of "1000000000000000000" with 18 decimals represents 1.0 tokens.
2. App Balances (appBalances
)
View positions within onchain applications like lending protocols, DEXes, etc.
To provide users with real-time portfolio data, use the computation endpoints to fetch and compute the latest balances for given address(s):
computeAppBalances
- Get current app positions, balances, and values.
Next, use balanceJobStatus
to return a jobID
. This checks computation status. Once a jobID
returns completed
, balances for that address(s) from portfolio
will be up-to-date.
Key Fields
address
: Position owner's addressappId
: Application identifierappName
: Display namebalanceUSD
: Total position value in USDnetwork
: Network where position existsproducts
: Detailed breakdown of positions by product typeappImage
: Application logo URL
Position balances come in two types that require GraphQL fragments to access their specific fields:
-
AppTokenPositionBalance
(for fungible tokens like LP tokens):balance
: Token balancebalanceUSD
: USD valueprice
: Token pricesymbol
: Token symbolsupply
: Total supplypricePerShare
: Underlying token ratios
-
ContractPositionBalance
(for positions like a masterchef farm):balanceUSD
: Position USD valuetokens
: Array of underlying tokens and their metadatadisplayProps
: Formatted data for UI rendering
Smart accounts like Maker's DSProxy
are automatically included in balance responses as part of an "implicit" bundle.
Example App Balance Query
query Portfolio($addresses: [Address!]!) {
portfolio(addresses: $addresses) {
appBalances {
appName
appId
network
products {
label
assets {
# App token positions (e.g. LP tokens)
... on AppTokenPositionBalance {
address
balance
balanceUSD
price
symbol
supply
displayProps {
label
images
}
}
# Contract positions (e.g. Masterchef Farm)
... on ContractPositionBalance {
address
balanceUSD
tokens {
metaType
token {
balance
symbol
price
}
}
displayProps {
label
images
}
}
}
}
}
}
}
Example Response
{
"data": {
"portfolio": {
"appBalances": [
{
"appName": "Lido",
"appId": "lido",
"network": "ETHEREUM_MAINNET",
"products": [
{
"label": "stETH",
"assets": [
{
"type": "app-token",
"balance": "0.011535336210992167",
"balanceUSD": 38.57116510214294,
"price": 3343.74,
"symbol": "stETH",
"supply": 9685583.98598499,
"displayProps": {
"label": "stETH",
"images": [
"https://storage.googleapis.com/zapper-fi-assets/tokens/ethereum/0x0000000000000000000000000000000000000000.png"
]
}
}
]
}
]
},
{
"appName": "GMX",
"appId": "gmx",
"network": "ARBITRUM_MAINNET",
"products": [
{
"label": "Farms",
"assets": [
{
"type": "contract-position",
"balanceUSD": 217.5294876331168,
"tokens": [
{
"metaType": "SUPPLIED",
"token": {
"balance": "123.19277851320523",
"symbol": "GLP",
"price": 1.4899571509867806
}
},
{
"metaType": "CLAIMABLE",
"token": {
"balance": "0.010176781691672002",
"symbol": "WETH",
"price": 3338.73
}
},
{
"metaType": "CLAIMABLE",
"token": {
"balance": "0",
"symbol": "esGMX",
"price": 28.09
}
}
],
"displayProps": {
"label": "GLP",
"images": [
"https://storage.googleapis.com/zapper-fi-assets/tokens/arbitrum/0x2f2a2543b76a4166549f7aab2e75bef0aefc5b0f.png",
"https://storage.googleapis.com/zapper-fi-assets/tokens/arbitrum/0x82af49447d8a07e3bd95bd0d56f35241523fbab1.png"
]
}
}
]
}
]
}
]
}
}
}
Fields
Main App Balance Fields
Field | Description | Type |
---|---|---|
key | Unique identifier for the position | String! |
address | Owner's wallet address | Address! |
appId | Unique identifier for the application | String! |
appName | Display name of the application | String! |
appImage | Application's logo URL | String! |
network | Network where the position exists | Network! |
balanceUSD | Total value of positions in USD | Float! |
updatedAt | Last time the position was updated | Timestamp! |
Products Fields
Field | Description | Type |
---|---|---|
label | Name of the product (e.g., "Farms", "Lending") | String! |
assets | Array of position assets | [AbstractPositionBalance!]! |
groupLabel | Categorical label for grouping related positions | String |
App Token Position Fields (e.g., LP Tokens)
Field | Description | Type |
---|---|---|
type | Type of position ("app-token") | String! |
address | Token contract address | Address! |
network | Network of the token | Network! |
balance | Token balance | String! |
balanceUSD | USD value of position | Float! |
price | Token price | Float! |
symbol | Token symbol | String! |
decimals | Token decimals | Float! |
supply | Total supply of token | Float! |
pricePerShare | Array of underlying token ratios | [Float!]! |
Contract Position Fields (e.g., Masterchef Farm)
Field | Description | Type |
---|---|---|
type | Type of position ("contract-position") | String! |
address | Contract address | Address! |
network | Network of the position | Network! |
balanceUSD | USD value of position | Float! |
Token Fields (Underlying Tokens)
Field | Description | Type |
---|---|---|
metaType | Token classification (e.g., "SUPPLIED", "BORROWED") | MetaTypeV3 |
type | Token type ("base-token") | String! |
address | Token contract address | Address! |
balance | Token balance | String! |
balanceUSD | USD value of token balance | Float! |
price | Token price | Float! |
symbol | Token symbol | String! |
decimals | Token decimals | Float! |
Display Props Fields
Field | Description | Type |
---|---|---|
label | Display name for the position | String! |
images | Array of image URLs related to position | [String!]! |
When working with token balances, remember to handle decimals correctly. For example, a balance of "1000000000" with 6 decimals represents 1,000 tokens.
Fields marked with !
are required fields in the response. The response structure will differ based on whether the position is an App Token Position (like LP tokens) or a Contract Position (like lending positions).
3. NFT Balances (nftBalances
)
Access NFT holdings and their estimated values.
Key Fields
network
: NFT's networkbalanceUSD
: Estimated total value in USD
NFT valuations use Zapper's algorithm but can be overridden with top offer, last sale, or custom values. NFTs can be hidden by owners to remove them from portfolio views.
Example NFT Balance Query
query ($addresses: [Address!]!, $networks: [Network!]) {
portfolio(addresses: $addresses, networks: $networks) {
nftBalances {
balanceUSD
network
}
}
}
If you need more information on the NFT holdings of a particular address, use nftUsersTokens
or nftUsersCollections
. Here you will find fields such as estimated values, traits, media, and marketplace data.
Example Response
{
"data": {
"portfolio": {
"nftBalances": [
{
"balanceUSD": 1662.061734333,
"network": "BASE_MAINNET"
}
]
}
}
}
4. Portfolio Totals (totals
)
Get aggregated portfolio values and breakdowns.
Key Fields
total
: Total portfolio value (excluding NFTs)totalWithNFT
: Total portfolio value (including NFTs)appsTotal
: Total value in app positionstotalByNetwork
: Breakdown by networktotalByNetworkWithNFT
: Network breakdown including NFTsclaimables
: Claimable token positionsdebts
: Outstanding debt positionsholdings
: Portfolio breakdown by category
Example Totals Query
query ($addresses: [Address!]!) {
portfolio(addresses: $addresses) {
totals {
total
totalWithNFT
totalByNetwork {
network
total
}
holdings {
label
balanceUSD
pct
}
}
}
}
Example Response
{
"data": {
"portfolio": {
"totals": {
"total": 11252.6887398181,
"totalByNetwork": [
{
"network": "ETHEREUM_MAINNET",
"total": 2936.7837588270454
},
{
"network": "ARBITRUM_MAINNET",
"total": 2540.454378130174
},
{
"network": "AVALANCHE_MAINNET",
"total": 173.0888443081786
},
{
"network": "BASE_MAINNET",
"total": 104.79617114576013
}
]
}
}
}
}
5. Claimables
View all available claimable tokens across indexed onchain apps.
Key Fields
address
: Address of the claimable tokenappId
: App where the token is claimabletoken
: Token details including balance, value, and metadata
Example Claimables Query
query Claimables($addresses: [Address!]!) {
portfolio(addresses: $addresses) {
totals {
claimables {
appId
address
token {
address
balanceUSD
balance
symbol
price
network
}
}
}
}
}
Example Response
{
"data": {
"portfolio": {
"totals": {
"claimables": [
{
"address": "0xe321bd63cde8ea046b382f82964575f2a5586474",
"appId": "uniswap-v3",
"token": {
"address": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2",
"balanceUSD": 3.987004980732349,
"balance": "0.001211064192315766",
"symbol": "WETH",
"price": 3292.15,
"network": "ETHEREUM_MAINNET"
}
}
]
}
}
}
}
Complete Response Structure
The portfolio query returns a nested structure that can include:
{
portfolio: {
// Token holdings
tokenBalances: [{
address: string
network: Network
token: {
balanceUSD: number
balance: number
baseToken: {
symbol: string
network: Network
imgUrl: string
}
}
}]
// App positions
appBalances: [{
appName: string
balanceUSD: number
appId: string
network: Network
products: [{
label: string
assets: [{ address: string }]
}]
}]
// NFT holdings
nftBalances: [{
network: Network
balanceUSD: number
}]
// Portfolio totals
totals: {
total: number
totalWithNFT: number
totalByNetwork: [{
network: Network
total: number
}]
holdings: [{
label: string
balanceUSD: number
pct: number
}]
claimables: [{
address: string
appId: string
token: {
address: string
balanceUSD: number
balance: string
symbol: string
price: number
network: Network
}
}]
}
}
}
Balance Computation
For any addresses that have never been tracked by Zapper before, balances need to be computed asynchronously before being fetched to ensure the most up-to-date portfolio data. The following mutations and query are designed for this purpose.
computeTokenBalances
Initiates a job to compute token balances for a wallet.
The input type for both mutations is PortfolioInput
:
input PortfolioInput {
"""The wallet addresses for which to fetch balances"""
addresses: [Address!]!
"""The networks for which to fetch balances"""
networks: [Network!]
"""The app slugs for which to fetch balances"""
appIds: [String!]
flagAsStale: Boolean
}
Example Variables
{
"input": {
"addresses": ["Habp5bncMSsBC3vkChyebepym5dcTNRYeg2LVG464E96"],
"networks": ["BITCOIN_MAINNET", "SOLANA_MAINNET"]
}
}
Example Mutation
mutation ComputeTokenBalances($input: PortfolioInput!) {
computeTokenBalances(input: $input) {
jobId
}
}
Example Response
{
"data": {
"computeTokenBalances": {
"jobId": "38b53084-9e84-46fd-a5fc-e7463baba936"
}
}
}
computeAppBalances
Initiates a job to compute app balances for a wallet.
Example Variables
{
"input": {
"addresses": [
"0x123...", // EVM address being tracked for first time
"Habp5bncMSsBC3vkChyebepym5dcTNRYeg2LVG464E96" // Solana address
],
"networks": ["ETHEREUM_MAINNET", "SOLANA_MAINNET"]
}
}
Example Mutation
mutation ComputeAppBalances($input: PortfolioInput!) {
computeAppBalances(input: $input) {
jobId
}
}
Example Response
{
"data": {
"computeAppBalances": {
"jobId": "176d50a0-c42b-49b1-a263-c1c4a63d8a3c"
}
}
}
balanceJobStatus
Query the status of a balance computation job.
Example Variables
{
"jobId": "176d50a0-c42b-49b1-a263-c1c4a63d8a3c"
}
Example Query
query BalanceJobStatus($jobId: String!) {
balanceJobStatus(jobId: $jobId) {
jobId
status
}
}
Example Response
{
"data": {
"balanceJobStatus": {
"jobId": "176d50a0-c42b-49b1-a263-c1c4a63d8a3c",
"status": "completed"
}
}
}
Response Fields
Field | Description | Type |
---|---|---|
jobId | Unique identifier for the computation job | ID! |
status | Current status of the job | String! |
Best Practices
- Always specify required fields to minimize response size
- Use network filters when you only need specific chains
- Consider caching responses based on the
updatedAt
timestamp - Handle NFT valuations appropriately based on your use case
Remember that the portfolio query is highly flexible - you can request as much or as little data as needed for your specific use case.