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.