Skip to main content

One call returns every asset a user holds

In the DeCard-Managed model, every end user holds their own wallet balance, kept in custody by DCS and ledgered per currency, and a single call returns the available, frozen and total amount of each of their assets. As a licensed issuer running its own BINs, DCS keeps this user-level ledger in custody for you, and both authorization and settlement act directly on that user’s own balance. This endpoint is how that model is exposed to you. A user can hold several assets at once, and the balance endpoint returns the available, frozen and total amount per currency. This page covers balance queries only. Money moving in, out and around is documented on the sibling pages, with no overlap:

The balance model: free / freeze / total

Under custody, DCS maintains three figures for each user and each asset:
When an authorization happens, free decreases, freeze increases and total is unchanged; at settlement (the actual deduction) the amount comes out of freeze and total falls with it. For how authorization and settlement rewrite these three figures, see Authorizing Transactions and Settlement; for the boundary of DCS custody, see Account and Asset Model (Ledgering).
Term alignment: the “availableBalance / frozenBalance” you may see in conceptual material are the free and freeze of this endpoint. Always integrate against the API field names free / freeze / total; availableBalance and frozenBalance are conceptual aliases only.

Prerequisites

  • The user is registered through Managing Users and you hold their externalUserId.
  • Balances are normally non-zero only after the user has passed KYC and assets have arrived (a top-up or a transfer); a new user may return an empty array or all zeros.
  • The caller is a partner onboarded to the DeCard-Managed model and sends the site-wide authentication headers (see Quickstart).

Endpoint contract

The user-asset module also offers credit, debit, transactions, transaction-detail and transfer-query, documented in Overview (transaction and statement queries) and Account and Asset Model (Ledgering) within this group. This page covers only the balance query. GET /user-asset/v1/balance
That is the only query parameter; there are no path parameters and no request body. This endpoint takes no path parameters and has no notion of a tenant, since balances are always read for one user keyed by externalUserId.

Request example

The usr_xxxxxxxx, key and signature in the example are all placeholders. Never paste a real user ID, API key or secret into any document, log or support ticket.

Response

The response uses the site-wide envelope { code, message, messageDetail, data }, where data is an array with one entry per asset the user holds, each describing the balance of one currency.
Fields of each data[] element:
data is an array, not a single object. Iterate over it by asset (and by network where that matters), and do not assume an object carrying availableBalance and frozenBalance fields.The site-wide response envelope is { code, message, messageDetail, data }, and on success the code literal is SYS_SUCCESS (identical in both integration models).

Error handling

  • The user does not exist, or externalUserId is invalid: code is not the success value, message and messageDetail explain why, and data carries no valid balance. Confirm first that the externalUserId was registered through the create-user endpoint.
  • A required parameter is missing: a request without externalUserId is rejected.
  • Authentication failure: a missing authentication header (X-DAPI-API-KEY / X-DAPI-SIGN / X-DAPI-TIMESTAMP / X-DAPI-NONCE), a bad signature or a replayed X-DAPI-NONCE all return the standard authentication error (see Quickstart).
  • Empty account: when the user exists but holds no assets yet, data may be an empty array [] or contain all zeros. That is not an error.

About the per-user account and DeCard-Managed model (why balances are queryable)

In the DeCard-Managed model, DCS holds each user’s funds in custody internally, keyed by externalUserId, with sub-accounts isolated per currency. That is precisely what allows this endpoint to return a balance per user and per currency. By contrast:
  • Partner-Managed: limits and authorization decisions belong to the partner, and DCS exposes no per-user balance endpoint.
  • DeCard-Managed (this documentation set): DCS keeps the user’s own balance in custody and decides authorizations internally, acting directly on that user’s free and freeze. This endpoint is how that model is exposed to you.
It also explains why whether an authorization succeeds depends mainly on whether the user’s free balance is sufficient and whether card transactions are blocked for that user; see Authorizing Transactions.

Real-time push of balance changes (WebSocket BALANCE_CHANGE)

Whenever an authorization, a settlement, a top-up (credit), a debit (debit) or an internal transfer changes a user’s free or freeze, DCS pushes a BALANCE_CHANGE event in real time over WebSocket, carrying freeDelta (the change in available balance), freezeDelta (the change in frozen balance) and the absolute free and freeze after the change. You do not need to poll /user-asset/v1/balance to track balances: subscribe to the WebSocket channel and receive the pushes. See Webhook & WebSocket.

Next steps