User asset balances
List the authenticated participant's token holdings through the DALP API, aggregated across their linked wallets, with balances, base-currency value, and yield denomination details.
Use the user asset balances endpoint when an integration needs the authenticated participant's current token holdings in a DALP system. It returns one row per token the participant holds, with the total, frozen, and available balance, the resolved base-currency value, the token's decimals, and a per-wallet breakdown.
The endpoint reads indexed balance state. It returns only tokens with a positive
balance in the active system, so an empty data array means the participant holds
no tracked assets in that system rather than that the data is missing.
Endpoint
GET /api/v2/user-asset-balancesThe endpoint 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 result is scoped to the active system from the request context. If a participant holds assets in more than one DALP system, the result for one system does not include rows from another system.
Read another participant's holdings
Send filter[wallet]=0x… to scope the result 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 still expands to that participant's full linked wallet set, so the response stays an aggregate-holdings view rather than a single-address view. This is the request the Console uses 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 request is rejected. When groupBy is set, 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 is one token the participant holds.
{
"data": [
{
"id": "0x71C7656EC7ab88b098defB751B7401B5f6d8976F",
"value": "1.000000000000000000",
"frozen": "0.000000000000000000",
"available": "1.000000000000000000",
"valueInBaseCurrency": "1000.00",
"priceInBaseCurrencyReliable": true,
"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, scaled 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. It isnullwhen no price path is available for the token.priceInBaseCurrencyReliable:falsewhen no price is available or when any conversion hop fell back to a stale rate, so a value still appears but should be treated with lower confidence.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 scaled by the token'sdecimals, matching the aggregate row.
The meta block reports 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.
Yield denomination details
For a token with a yield schedule, token.yield.schedule.denominationAsset
reports the asset the schedule pays in, with its symbol and decimals. The
platform resolves the denomination token's metadata within the active system
scope, so use the reported decimals to scale denomination amounts rather than
assuming 18.
When the denomination asset is not resolvable in the active system scope, or the
yield schedule has no recorded denomination asset, the denomination block falls
back to the schedule address with a placeholder UNKNOWN symbol and 18 decimals.
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.
- Token holders and transfers for per-token holder balances and transfer operations.
- Getting started with API integration
Portfolio statistics
Query a participant's portfolio value time series and breakdowns, aggregated across their linked wallets, for the active DALP system.
Token features API
Reference index for the eleven DALP token features and the Platform API endpoints that configure and operate them during asset creation and servicing.