User asset balances
List the authenticated participant's token holdings through the DALP API, aggregated across their linked wallets, with balances, base-currency value, cost basis, and unrealized profit and loss.
Call this route to retrieve the authenticated participant's token holdings. Results are aggregated across all linked wallets, so each row represents one token position rather than one address. The response includes total, frozen, and available balances, a resolved base-currency value, a per-wallet breakdown for audit, and the cost basis and unrealized profit and loss of each position.
The route reads indexed balance state. When you receive an empty data array,
the participant holds no tracked assets in the active system; the data is not
missing.
Endpoint
GET /api/v2/user-asset-balancesIt returns a JSON:API paginated collection with data, meta, and
links. Each data item is one aggregated token balance for the participant.
curl --globoff --request GET \
"$DALP_API_URL/api/v2/user-asset-balances?page[limit]=50&sort=-balance" \
--header "X-Api-Key: $DALP_API_TOKEN"Holder scope and wallet aggregation
Balances are calculated for the authenticated participant, not for a single address. A participant can hold the same token through more than one linked wallet, typically a signing account (EOA) and a smart wallet under account abstraction. By default the endpoint aggregates each token's balance across the participant's full set of linked wallets in the active system, so an account-abstraction user sees one combined balance per token without your integration fetching and summing each address separately.
Each row also includes a byWallet array that breaks the aggregate balance down
per wallet, so you can show both the combined total and the per-wallet split.
The response is scoped to the active system from your request context. If a participant holds assets in more than one DALP system, each system's data covers only that system's rows.
Read another participant's holdings
Send filter[wallet]=0x… to scope the response to a specific wallet instead of the
authenticated participant's own holdings. The platform honors the override for the
participant reading their own wallet, for platform admins reading any wallet, and
for active-organization user readers when the target wallet belongs to a user in
the caller's current organization. An organization user reader requesting a wallet
outside their organization is rejected with FORBIDDEN.
An honored override that resolves to a participant expands to that participant's full linked wallet set, so the response stays an aggregate-holdings view rather than a single-address view. A platform admin requesting a wallet that is not attached to any participant reads that single wallet only. The Console uses this pattern to show another user's holdings on a participant detail workspace without requiring platform admin access.
Query parameters
The endpoint uses the canonical collection query parameters.
| Parameter | Use it for |
|---|---|
page[limit] | Page size. Defaults to 50, with a maximum of 200. |
page[offset] | Number of rows to skip for pagination. |
sort | Sort order. Defaults to -balance (largest balance first). |
filter[q] | Global search across the token name and symbol. |
filter[wallet] | Gated wallet override described above. |
filter[<field>] | Filter by tokenAddress, tokenName, tokenSymbol, or tokenDecimals. |
filter[metadata.<key>] | Filter by a metadata key declared on the token's asset-type template. |
groupBy | Group results by a bucketable metadata key and return per-group summaries (see below). |
sort accepts balance, tokenAddress, tokenName, and tokenSymbol. Prefix a
field with - for descending order. tokenDecimals can be filtered but not
sorted.
Group by a metadata key
Send groupBy=<key> to group the participant's filtered holdings by a bucketable
metadata key declared on the token's asset-type template. The key must be declared
and bucketable, otherwise the platform rejects the request. When you set groupBy,
the response meta block adds a groups array of per-group summaries and a
groupBy object naming the active axis and its display label. A returned row
carries a metadataValues object holding the grouped key's value only when the
token has a value for that key; rows without a value for the grouped key omit the
field.
Response shape
Each data item represents one token the participant holds. Fields are described after the example.
{
"data": [
{
"id": "0x71C7656EC7ab88b098defB751B7401B5f6d8976F",
"value": "1.000000000000000000",
"frozen": "0.000000000000000000",
"available": "1.000000000000000000",
"valueInBaseCurrency": "1000.00",
"priceInBaseCurrencyReliable": true,
"priceChange24hPercent": "2.50",
"priceAsOf24h": "975.61",
"costBasis": "900.00",
"unrealizedPnl": "100.00",
"unrealizedPnlPercent": "11.11",
"costBasisIncomplete": false,
"token": {
"id": "0x71C7656EC7ab88b098defB751B7401B5f6d8976F",
"name": "Bond Token",
"symbol": "BOND",
"type": "bond",
"isExternal": false,
"decimals": 18,
"totalSupply": "1000000",
"bond": { "isMatured": false },
"yield": {
"schedule": {
"id": "0x8ba1f109551bD432803012645Ac136ddd64DBA72",
"denominationAsset": {
"id": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
"symbol": "USDC",
"decimals": 6
}
}
}
},
"byWallet": [
{
"wallet": "0x71C7656EC7ab88b098defB751B7401B5f6d8976F",
"value": "1.000000000000000000",
"frozen": "0.000000000000000000",
"available": "1.000000000000000000"
}
]
}
],
"meta": {
"total": 1,
"facets": {}
},
"links": {
"self": "/v2/user-asset-balances?page[limit]=50&page[offset]=0",
"first": "/v2/user-asset-balances?page[limit]=50&page[offset]=0",
"prev": null,
"next": null,
"last": "/v2/user-asset-balances?page[limit]=50&page[offset]=0"
}
}Each item includes:
id: the token contract address for the aggregated balance row.value,frozen,available: the total, frozen, and available balance, adjusted by the token'sdecimalsand returned as decimal strings.valueInBaseCurrency: the balance multiplied by the token's resolved price, expressed in the organization's base currency. The field isnullwhen no price path is available for the token.priceInBaseCurrencyReliable:falsewhen no price path is available, in which casevalueInBaseCurrencyis alsonull, or when a price is returned but a conversion hop fell back to a stale rate. When a value is present and this flag isfalse, treat the value with lower confidence.priceChange24hPercent: the signed percentage change of the token's base-currency price over the trailing 24-hour window. The field isnullwhen no current price exists or no price observation is at least 24 hours old.priceAsOf24h: the token's base-currency price as of 24 hours ago, taken from the nearest earlier observation and used as the baseline forpriceChange24hPercent. The field isnullwhen no observation is at least 24 hours old.costBasis: the weighted-average cost basis of the held quantity, summed across the participant's wallets that hold this token and expressed in the organization's base currency. The field isnullwhen no cost-basis record covers any contributing wallet.unrealizedPnl: the unrealized gain or loss on the holding, equal tovalueInBaseCurrencyminuscostBasis, in the base currency. The field isnullwhen either the current value or the cost basis is unavailable.unrealizedPnlPercent:unrealizedPnlas a percentage ofcostBasis. The field isnullwhen the cost basis is unavailable or zero.costBasisIncomplete:truewhen at least one acquisition that contributed to the holding had no resolvable price at the time of acquisition. When this flag istrue,costBasisandunrealizedPnlunderstate the true figures, so treat them as a lower bound.token: the token's name, symbol, type, decimals, total supply, and feature details such as bond maturity and yield.byWallet: the per-wallet breakdown of the aggregate balance, with each wallet'svalue,frozen, andavailablereturned as decimal strings adjusted by the token'sdecimals, matching the aggregate row.
The meta block includes total, the count of distinct tokens matching the
request, and facets, the available metadata facet axes for the result. When a
request sets groupBy, meta also includes groups and groupBy.
Cost basis and unrealized profit and loss
Each holding carries the cost basis and unrealized profit and loss of the open position. An integration can show what a participant currently holds and how that holding is performing without a second request. These figures cover open positions only. For gains and losses already locked in by disposing of tokens, read the realized P&L statistics endpoints instead.
costBasis is the weighted-average cost of the held quantity in the
organization's base currency, aggregated across the wallets that hold the token.
unrealizedPnl subtracts that cost from the current valueInBaseCurrency, and
unrealizedPnlPercent expresses the same gain or loss as a percentage of cost.
When costBasisIncomplete is true, one or more acquisitions had no price on
record at the time they were acquired, so the reported cost basis and unrealized
P&L are a lower bound rather than the exact figures. Surface that caveat to the
reader when you display the numbers.
Behavior while reporting data rebuilds
Cost basis and unrealized P&L come from reporting data that the platform
rebuilds in the background, for example after a system upgrade. While that
process runs, this endpoint keeps returning the holdings list: each row still
carries its balances, base-currency value, and price fields, while the
cost-basis enrichment degrades to null for the affected tokens until the
rebuild completes. Balances never disappear when those numbers are not yet
available.
During a rebuild, a row's costBasis, unrealizedPnl, and unrealizedPnlPercent
return null for the same reason they return null when a holding has no
cost-basis record at all: those numbers are unavailable. This endpoint does not
signal which of the two caused a given null. To tell a transient rebuild apart
from a holding that genuinely has no recorded acquisition price, retry the
request. A rebuild-induced null resolves to real figures once the rebuild
completes, while a holding with no recorded acquisition price stays null.
The dedicated profit-and-loss endpoints behave differently. The
realized P&L statistics
endpoints do not degrade to partial data during a rebuild. They return the
retryable DALP-0083 error with a 503 status while the reporting data is
rolling out, so an integration should retry them after the rollout completes.
See the
platform API error reference
for the full retry contract. Use this difference to decide where to read each
figure. Read holdings and balances from this endpoint, where they always render.
Read realized gains and losses from the dedicated endpoints, where a 503 tells
you to wait and retry rather than returning incomplete numbers.
Yield denomination details
For a token with a yield schedule, token.yield.schedule.denominationAsset
identifies the asset the schedule pays in, with its symbol and decimals. The
platform resolves that token's metadata by chain and
address, so a 6-decimal denomination asset returns "decimals": 6 even when that
asset sits outside the participant's active system scope. Use the reported
decimals to convert denomination amounts rather than assuming 18.
When the schedule records a denomination asset address but its metadata is not
found, denominationAsset.id keeps that denomination asset address while symbol
and decimals fall back to UNKNOWN and 18. When the schedule has no recorded
denomination asset at all, denominationAsset.id is the schedule address with the
same UNKNOWN/18 fallback.
Errors
| Condition | Result |
|---|---|
| The participant has no wallet on file in the active system. | UNAUTHORIZED |
A filter[wallet] override targets a wallet the caller may not read. | FORBIDDEN |
See the platform API error reference for the full error contract.
Related
- Portfolio statistics for the participant's aggregate value time series and asset-type breakdown.
- Realized P&L statistics for the participant's realized gains and losses on disposed holdings.
- Token holders and transfers for per-token holder balances and transfer operations.
- Getting started with API integration
System asset statistics API
Read the asset count, value breakdown, and creation and activity trends for a DALP system through the Platform API, as current figures or as time series for dashboards and reporting.
Token features
Reference index for the thirteen DALP token features and the Platform API endpoints that configure and operate them during asset creation and servicing.