Skip to main content

Balance Management API

This document describes the Balance Management endpoints for querying customer and account balances in Link Core.

Endpoints​


Get Customer Balances​

Retrieves all asset balances for a specific customer across all their accounts.

Endpoint: GET /balances/customer/:customerId

Path Parameters​

ParameterTypeRequiredDescription
customerIdstringYesCustomer identifier

Query Parameters​

ParameterTypeRequiredDescription
filter[assetCode]stringNoFilter by specific asset code (e.g., "BTC")
filter[assetId]string (UUID)NoFilter by specific asset ID
filter[accountId]stringNoFilter by specific account ID

Response​

Status: 200 OK

[
{
"customerId": "customer-123",
"accountId": "account-456",
"assetId": "btc-asset-id",
"assetCode": "BTC",
"assetName": "Bitcoin",
"availableBalance": "1.5",
"frozenBalance": "0.0",
"totalBalance": "1.5"
},
{
"customerId": "customer-123",
"accountId": "account-456",
"assetId": "eth-asset-id",
"assetCode": "ETH",
"assetName": "Ethereum",
"availableBalance": "10.25",
"frozenBalance": "2.5",
"totalBalance": "12.75"
}
]

Response Fields​

FieldTypeDescription
customerIdstringCustomer identifier
accountIdstringAccount identifier
assetIdstring (UUID)Digital asset identifier
assetCodestringAsset ticker symbol (e.g., "BTC", "ETH")
assetNamestringAsset display name
availableBalancestringAvailable balance (spendable)
frozenBalancestringFrozen balance (pending transactions, holds)
totalBalancestringTotal balance (available + frozen)

Examples​

Get All Balances for Customer​

curl -X GET "https://api.ledgerlink.ai/v1/balances/customer/customer-123"

Response:

[
{
"customerId": "customer-123",
"accountId": "account-456",
"assetId": "btc-asset-id",
"assetCode": "BTC",
"assetName": "Bitcoin",
"availableBalance": "1.5",
"frozenBalance": "0.0",
"totalBalance": "1.5"
},
{
"customerId": "customer-123",
"accountId": "account-456",
"assetId": "eth-asset-id",
"assetCode": "ETH",
"assetName": "Ethereum",
"availableBalance": "10.25",
"frozenBalance": "2.5",
"totalBalance": "12.75"
},
{
"customerId": "customer-123",
"accountId": "account-789",
"assetId": "usdc-asset-id",
"assetCode": "USDC",
"assetName": "USD Coin",
"availableBalance": "5000.00",
"frozenBalance": "0.0",
"totalBalance": "5000.00"
}
]

Filter by Specific Asset Code​

curl -X GET "https://api.ledgerlink.ai/v1/balances/customer/customer-123?filter[assetCode]=BTC"

Response:

[
{
"customerId": "customer-123",
"accountId": "account-456",
"assetId": "btc-asset-id",
"assetCode": "BTC",
"assetName": "Bitcoin",
"availableBalance": "1.5",
"frozenBalance": "0.0",
"totalBalance": "1.5"
}
]

Filter by Asset ID​

curl -X GET "https://api.ledgerlink.ai/v1/balances/customer/customer-123?filter[assetId]=eth-asset-id"

Response:

[
{
"customerId": "customer-123",
"accountId": "account-456",
"assetId": "eth-asset-id",
"assetCode": "ETH",
"assetName": "Ethereum",
"availableBalance": "10.25",
"frozenBalance": "2.5",
"totalBalance": "12.75"
}
]

Filter by Specific Account​

curl -X GET "https://api.ledgerlink.ai/v1/balances/customer/customer-123?filter[accountId]=account-456"

Response:

[
{
"customerId": "customer-123",
"accountId": "account-456",
"assetId": "btc-asset-id",
"assetCode": "BTC",
"assetName": "Bitcoin",
"availableBalance": "1.5",
"frozenBalance": "0.0",
"totalBalance": "1.5"
},
{
"customerId": "customer-123",
"accountId": "account-456",
"assetId": "eth-asset-id",
"assetCode": "ETH",
"assetName": "Ethereum",
"availableBalance": "10.25",
"frozenBalance": "2.5",
"totalBalance": "12.75"
}
]

Error Responses​

404 Not Found​

{
"statusCode": 404,
"message": "Customer not found",
"error": "Not Found"
}

Causes:

  • Customer ID does not exist
  • No balances found for customer

400 Bad Request​

{
"statusCode": 400,
"message": "Invalid filter parameters",
"error": "Bad Request"
}

Causes:

  • Invalid UUID format for assetId
  • Invalid filter syntax

Get Account Balances​

Retrieves all asset balances for a specific account.

Endpoint: GET /balances/account/:accountId

Path Parameters​

ParameterTypeRequiredDescription
accountIdstringYesAccount identifier

Query Parameters​

ParameterTypeRequiredDescription
filter[assetCode]stringNoFilter by specific asset code (e.g., "BTC")
filter[assetId]string (UUID)NoFilter by specific asset ID

Response​

Status: 200 OK

[
{
"customerId": "customer-123",
"accountId": "account-456",
"assetId": "btc-asset-id",
"assetCode": "BTC",
"assetName": "Bitcoin",
"availableBalance": "1.5",
"frozenBalance": "0.0",
"totalBalance": "1.5"
},
{
"customerId": "customer-123",
"accountId": "account-456",
"assetId": "eth-asset-id",
"assetCode": "ETH",
"assetName": "Ethereum",
"availableBalance": "10.25",
"frozenBalance": "2.5",
"totalBalance": "12.75"
}
]

Examples​

Get All Balances for Account​

curl -X GET "https://api.ledgerlink.ai/v1/balances/account/account-456"

Response:

[
{
"customerId": "customer-123",
"accountId": "account-456",
"assetId": "btc-asset-id",
"assetCode": "BTC",
"assetName": "Bitcoin",
"availableBalance": "1.5",
"frozenBalance": "0.0",
"totalBalance": "1.5"
},
{
"customerId": "customer-123",
"accountId": "account-456",
"assetId": "eth-asset-id",
"assetCode": "ETH",
"assetName": "Ethereum",
"availableBalance": "10.25",
"frozenBalance": "2.5",
"totalBalance": "12.75"
}
]

Filter by Asset Code​

curl -X GET "https://api.ledgerlink.ai/v1/balances/account/account-456?filter[assetCode]=ETH"

Response:

[
{
"customerId": "customer-123",
"accountId": "account-456",
"assetId": "eth-asset-id",
"assetCode": "ETH",
"assetName": "Ethereum",
"availableBalance": "10.25",
"frozenBalance": "2.5",
"totalBalance": "12.75"
}
]

Error Responses​

404 Not Found​

{
"statusCode": 404,
"message": "Account not found",
"error": "Not Found"
}

Causes:

  • Account ID does not exist
  • No balances found for account

Balance Concepts​

Available Balance​

The available balance represents the amount that can be immediately used for transactions:

Available Balance = Total Balance - Frozen Balance

Use Cases:

  • Check if customer can withdraw requested amount
  • Display spendable balance in UI
  • Validate transaction requests

Frozen Balance​

The frozen balance represents amounts that are temporarily locked:

Common Reasons for Frozen Balance:

  • Pending withdrawals awaiting screening
  • Pending deposits awaiting confirmation
  • Transactions flagged for manual review (status: FROZEN)
  • Risk management holds
  • Regulatory compliance holds

Frozen Balance Lifecycle:

  1. Transaction created → Amount frozen
  2. Transaction approved → Amount unfrozen, processed
  3. Transaction rejected → Amount unfrozen, returned

Total Balance​

The total balance is the sum of available and frozen amounts:

Total Balance = Available Balance + Frozen Balance

Use Cases:

  • Display total holdings in portfolio
  • Calculate net worth
  • Reporting and analytics

Balance Filtering​

By Asset Code​

Filter balances by asset ticker symbol (case-insensitive):

GET /balances/customer/:customerId?filter[assetCode]=BTC
GET /balances/customer/:customerId?filter[assetCode]=eth

By Asset ID​

Filter balances by specific asset UUID:

GET /balances/customer/:customerId?filter[assetId]=btc-asset-id

By Account ID (Customer Endpoint Only)​

When querying customer balances, filter to a specific account:

GET /balances/customer/:customerId?filter[accountId]=account-456

Multiple Filters​

Combine filters (implementation-dependent):

GET /balances/customer/:customerId?filter[assetCode]=BTC&filter[accountId]=account-456

Common Use Cases​

Check Withdrawal Eligibility​

Before initiating a withdrawal, verify sufficient available balance:

# Get balance
GET /balances/customer/customer-123?filter[assetCode]=BTC

# Response
[
{
"assetCode": "BTC",
"availableBalance": "1.5",
"frozenBalance": "0.0",
"totalBalance": "1.5"
}
]

# Can withdraw up to 1.5 BTC

Display Portfolio​

Get all balances for portfolio display:

GET /balances/customer/customer-123

Display totalBalance for each asset in portfolio UI.

Monitor Frozen Amounts​

Check frozen balances to track pending transactions:

GET /balances/customer/customer-123

# Look for assets with frozenBalance > 0
[
{
"assetCode": "ETH",
"availableBalance": "10.25",
"frozenBalance": "2.5", // ← 2.5 ETH locked
"totalBalance": "12.75"
}
]

Account-Specific Balances​

For multi-account customers, query specific account:

# Get balances for specific account
GET /balances/account/account-456

# Or filter customer balances by account
GET /balances/customer/customer-123?filter[accountId]=account-456

Integration Notes​

Balance Updates​

Balances are updated automatically by Link Core:

Deposits:

  1. Transaction created → No balance change
  2. Screening approved → Amount frozen (if implemented)
  3. Transaction completed → Available balance increased

Withdrawals:

  1. Transaction created → Amount frozen (deducted from available)
  2. Screening approved → Blockchain transaction initiated
  3. Transaction completed → Frozen amount removed (already deducted)

Rejections:

  1. Transaction rejected → Frozen amount returned to available

Real-time Balances​

Balance queries return real-time data:

  • No caching by default
  • Always reflects latest transaction state
  • Suitable for transaction validation

Precision​

All balance amounts are returned as decimal strings to preserve precision:

{
"availableBalance": "1.50000000",
"frozenBalance": "0.00000000",
"totalBalance": "1.50000000"
}

Important: Use decimal/BigDecimal libraries for arithmetic, never floating-point.

Empty Balances​

If no balances exist for a customer/account:

[]

An empty array is returned (not an error).


Error Handling​

Customer/Account Not Found​

If the customer or account doesn't exist, a 404 error is returned:

{
"statusCode": 404,
"message": "Customer not found",
"error": "Not Found"
}

Recommendation: Create customer/account first before querying balances.

Invalid Filters​

If filter parameters are invalid:

{
"statusCode": 400,
"message": "Invalid filter parameters",
"error": "Bad Request"
}

Common Issues:

  • Malformed UUID in filter[assetId]
  • Invalid filter syntax

Best Practices​

1. Filter by Asset When Possible​

For better performance, filter by specific asset:

# Good: Specific asset query
GET /balances/customer/customer-123?filter[assetCode]=BTC

# Slower: All assets
GET /balances/customer/customer-123

2. Use Available Balance for Validations​

Always check availableBalance before initiating withdrawals:

const balance = await getCustomerBalances(customerId, { assetCode: 'BTC' });
if (parseFloat(balance.availableBalance) < withdrawalAmount) {
throw new Error('Insufficient available balance');
}

3. Display Both Available and Total​

In UI, show both balances for transparency:

BTC Balance
Available: 1.5 BTC
Frozen: 0.0 BTC
Total: 1.5 BTC

4. Handle Zero Balances​

Display assets with zero balance based on UI requirements:

// Option 1: Show all assets (including zero)
const allBalances = await getCustomerBalances(customerId);

// Option 2: Filter out zero balances
const nonZeroBalances = allBalances.filter(b =>
parseFloat(b.totalBalance) > 0
);

Need Help? Contact helpdesk@ledgerlink.ai for assistance.