Z Zise Developers 简体中文

Member balances by asset (eight buckets)

GET /v1/balances scope: balances:read
On behalf of a member · x-on-behalf-of required

One row per asset with eight independent buckets. These are not different views of one total, but eight nonoverlapping balances. The member's total for the asset is their sum.

  • available Member available balance. Self-operated business may use it; external merchant orders use merchant prepaid funds.
  • pending: incoming. Deposits detected but not yet confirmed. External merchants cannot create member deposits; historical balances remain for reconciliation.
  • frozen: frozen. Funds frozen by operations/risk controls per member and asset. Only our administration system can unfreeze them; merchants have no unlock endpoint.
  • isolated: isolated. Funds segregated during disputes, legal assistance, or anti-money-laundering investigations. Separate from frozen because the handling process differs; do not merge their display.
  • locked: business holds. When an asynchronous, potentially failing order such as a remittance is created, funds move here from available. At the final outcome they are either settled or returned to available.
  • card: funds on cards. Money already sent to the issuing upstream, physically outside our platform. Only card-issuing endpoints may move it. Do not include it in how much the user can still spend from the wallet.
  • earn: wealth products. Principal invested in flexible or fixed-term products.
  • withdrawing: withdrawals in progress. Funds moved from available by POST /v1/withdrawals. The only exits are confirm, which clears the hold, or fail, which returns funds to available. Operations cannot modify it, and merchants have no third path.

The eight amounts are integer strings in the smallest unit, with no decimal point. Precision is that row's ledger_scale. At ledger_scale 6, 1250 USDT is "1250000000", not "1250.000000".

⚠ Returns assets for which this member already has account rows, not the asset catalog. A member who has never received funds gets an empty array, not a list of 0 balances. To show every selectable asset, also fetch GET /v1/assets and outer-join the two lists.

⚠ The response envelope was standardized to { data, next_cursor, has_more } on 2026-08-13. This endpoint is not paginated and will not be: next_cursor is always null and has_more always false, explicitly indicating a complete list rather than missing fields. Your generic paginator therefore needs no special branch here.

balances is still returned and references the same array as data, but is a transitional compatibility field retained for integrations predating the change. New integrations must read data; existing balances readers should migrate. Its removal will be announced in the changelog, with no second compatibility fallback afterward.

Prerequisites

  • The member belongs to this Key's merchant; otherwise always returns member_not_found, identical to a nonexistent member.
FieldTypeRequiredDescription
x-on-behalf-of string Required Whose balance to query. Accepts both the merchant's own external_member_id and our mem_<uuid> returned in member responses.

Response

200OK
{
  "data": [
    {
      "asset": "USDT",
      "available": "1250000000",
      "pending": "0",
      "frozen": "0",
      "isolated": "0",
      "locked": "300000000",
      "card": "0",
      "earn": "5000000000",
      "withdrawing": "0",
      "ledger_scale": 6,
      "display_scale": 2
    },
    {
      "asset": "USD",
      "available": "48750000",
      "pending": "0",
      "frozen": "0",
      "isolated": "0",
      "locked": "0",
      "card": "120000000",
      "earn": "0",
      "withdrawing": "0",
      "ledger_scale": 6,
      "display_scale": 2
    }
  ],
  "next_cursor": null,
  "has_more": false,
  "balances": [
    {
      "asset": "USDT",
      "available": "1250000000",
      "pending": "0",
      "frozen": "0",
      "isolated": "0",
      "locked": "300000000",
      "card": "0",
      "earn": "5000000000",
      "withdrawing": "0",
      "ledger_scale": 6,
      "display_scale": 2
    },
    {
      "asset": "USD",
      "available": "48750000",
      "pending": "0",
      "frozen": "0",
      "isolated": "0",
      "locked": "0",
      "card": "120000000",
      "earn": "0",
      "withdrawing": "0",
      "ledger_scale": 6,
      "display_scale": 2
    }
  ]
}
400member_context_required: missing x-on-behalf-of.
404member_not_found: nonexistent member, belonging to another merchant, or suspended. All three return the same response; do not use it to determine whether a member exists.
Request
curl -X GET 'https://api.zinfra.vip/v1/balances' \
  -H 'x-auth-token: Bearer $TOKEN' \
  -H 'x-on-behalf-of: $MEMBER_ID'
const res = await fetch("https://api.zinfra.vip/v1/balances", {
  method: "GET",
  headers: {
    "x-auth-token": "Bearer $TOKEN",
    "x-on-behalf-of": "$MEMBER_ID",
  },
});
// Keep monetary amounts as strings, never numbers.
const data = await res.json();
import requests

res = requests.get(
    "https://api.zinfra.vip/v1/balances",
    headers={
        "x-auth-token": "Bearer $TOKEN",
        "x-on-behalf-of": "$MEMBER_ID",
    },
)
# Use Decimal(str(...)) for amounts, not float.
data = res.json()
req, _ := http.NewRequest("GET", "https://api.zinfra.vip/v1/balances",
    nil)
req.Header.Set("x-auth-token", "Bearer $TOKEN")
req.Header.Set("x-on-behalf-of", "$MEMBER_ID")
res, err := http.DefaultClient.Do(req)
// Decode amount fields as string, not float64.
HttpRequest req = HttpRequest.newBuilder()
    .uri(URI.create("https://api.zinfra.vip/v1/balances"))
    .header("x-auth-token", "Bearer $TOKEN")
    .header("x-on-behalf-of", "$MEMBER_ID")
    .method("GET", HttpRequest.BodyPublishers.noBody())
    .build();
// Use String / BigDecimal for amounts, not double.
$ch = curl_init('https://api.zinfra.vip/v1/balances');
curl_setopt_array($ch, [
  CURLOPT_CUSTOMREQUEST => 'GET',
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HTTPHEADER => [
    'x-auth-token: Bearer $TOKEN',
    'x-on-behalf-of: $MEMBER_ID',
  ],
]);
$res = curl_exec($ch);
// Use bcmath / strings for amounts, not floatval.
200
{
  "data": [
    {
      "asset": "USDT",
      "available": "1250000000",
      "pending": "0",
      "frozen": "0",
      "isolated": "0",
      "locked": "300000000",
      "card": "0",
      "earn": "5000000000",
      "withdrawing": "0",
      "ledger_scale": 6,
      "display_scale": 2
    },
    {
      "asset": "USD",
      "available": "48750000",
      "pending": "0",
      "frozen": "0",
      "isolated": "0",
      "locked": "0",
      "card": "120000000",
      "earn": "0",
      "withdrawing": "0",
      "ledger_scale": 6,
      "display_scale": 2
    }
  ],
  "next_cursor": null,
  "has_more": false,
  "balances": [
    {
      "asset": "USDT",
      "available": "1250000000",
      "pending": "0",
      "frozen": "0",
      "isolated": "0",
      "locked": "300000000",
      "card": "0",
      "earn": "5000000000",
      "withdrawing": "0",
      "ledger_scale": 6,
      "display_scale": 2
    },
    {
      "asset": "USD",
      "available": "48750000",
      "pending": "0",
      "frozen": "0",
      "isolated": "0",
      "locked": "0",
      "card": "120000000",
      "earn": "0",
      "withdrawing": "0",
      "ledger_scale": 6,
      "display_scale": 2
    }
  ]
}