Skip to main content

GET /v1/balances

Returns the caller's per-currency balance snapshot — one row per (currency, network) for which a balance record exists on this account.

Method & pathGET /v1/balances
Required permissionread_balance
AuthHMAC — see Authentication

Query parameters

NameTypeRequiredDescription
currencystringoptionalFilter to a single currency symbol (case-insensitive on the server, but sign with the exact case you'll send).
networkstringoptionalFilter to a single network code (e.g. ETH, BSC, TRX).

Pass both to drill down to a single (currency, network) row.

Response

{
"success": true,
"message": "OK",
"data": [
{
"currency": "USDT",
"network": "ETH",
"balance": "1500.000000",
"held": "200.000000",
"available": "1300.000000"
}
],
"data_count": 1
}
FieldTypeDescription
currencystringCurrency symbol.
networkstringNetwork code.
balancestringConfirmed credited balance at this currency's full decimal precision. Always a string — never parse as a JS number.
heldstringAmount currently reserved by in-flight withdrawals (not yet confirmed).
availablestringbalance - held. Spendable amount, the right number to display in your UI as "available".

Decimals are strings across the entire API so there's no float precision loss. Parse with decimal.Decimal (Python), BigNumber.js (Node), or similar.

Errors

Standard middleware errors only — no business-logic failures on this read endpoint. See the Errors page for the full catalog.

StatusCause
401Missing or invalid signature / timestamp / nonce.
403Key lacks read_balance, or source IP not whitelisted.
429Rate limit exceeded.

Code samples

Each sample assumes the sign_request(...) helper from the Authentication page is in scope. Only the request itself is shown.

METHOD="GET"
ENDPOINT="/v1/balances"
QUERY="currency=USDT&network=ETH"
BODY=""

# ... sign exactly as on the Authentication page (same TS / BODY_HASH / CANONICAL / SIG block) ...

curl -sS "${BASE_URL}${ENDPOINT}?${QUERY}" \
-H "X-CPG-Key: ${API_KEY}" \
-H "X-CPG-Timestamp: ${TS}" \
-H "X-CPG-Signature: ${SIG}"

Notes

  • Not paginated. The response is one row per (currency, network) balance record — usually a small set (fewer than 20 rows). The envelope carries data + data_count only; there are no cursor / next_cursor / has_more fields.
  • held is updated optimistically. It bumps the moment you submit a withdrawal (POST /v1/withdrawals) and clears when that withdrawal either confirms (becomes a real balance decrement) or fails (released back). So available in this response is a true spendable number — you can call POST /v1/withdrawals again immediately for any available amount without risk of double-spending.
  • Sign the exact query string you'll send. The middleware reconstructs the canonical string from request.url.query. If you sign currency=USDT&network=ETH but your HTTP client transmits network=ETH&currency=USDT, the signature won't match.