Query Dedicated Funds Card Balance
Overview
Use this endpoint to query the available balance of a Dedicated Funds Card. This endpoint is specifically for Dedicated Funds Cards only (cards with their own independent balance). For Shared Funds Cards, balances are managed through budget accounts instead.
NOTE: This API is offered on a client-by-client approval basis. Speak to your account manager to check eligibility.
IMPORTANT: This endpoint only works for Dedicated Funds Cards. It will not work for Shared Funds Cards.
Resource Access
Production (api.ahrvo.network)
GET https://api.ahrvo.network/card/issuance/api/issuing/card/v2/normal/balance
Staging (gateway.ahrvo.network)
GET https://gateway.ahrvo.network/card/issuance/api/issuing/card/v2/normal/balance
Request Headers
| Header | Value | Required | Description |
|---|---|---|---|
Accept | application/json | Yes | Content type for the response |
Authorization | Bearer {access_token} | Yes | Bearer token for authentication |
x-api-key | API Key | Yes | API key for authentication |
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
card_id | string | Yes | A unique ID of the card |
Response
Success Response (200 OK)
{
"code": "SUCCESS",
"data": {
"card_number": "5157********2686",
"available_balance": "1468.87"
}
}
Response Fields
| Field | Type | Description |
|---|---|---|
code | string | Status string indicating the result. "SUCCESS" refers to a successful query |
data | object | Response data object |
data.card_number | string | Masked card number (e.g., 5157****8888) |
data.available_balance | string | Available balance of the Dedicated Funds Card (in USD) |
Error Responses
- 400 Bad Request: Invalid
card_idor card is not a Dedicated Funds Card - 401 Unauthorized: Invalid or missing authentication token
- 403 Forbidden: Card issuance feature not enabled for this account
- 404 Not Found: Card does not exist
Code Examples
cURL
curl -X GET \
'https://gateway.ahrvo.network/card/issuance/api/issuing/card/v2/normal/balance?card_id=card201907021723076245' \
-H 'Accept: application/json' \
-H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
-H 'x-api-key: YOUR_API_KEY'
Python
import requests
url = "https://gateway.ahrvo.network/card/issuance/api/issuing/card/v2/normal/balance"
headers = {
"Accept": "application/json",
"Authorization": "Bearer YOUR_ACCESS_TOKEN",
"x-api-key": "YOUR_API_KEY"
}
params = {
"card_id": "card201907021723076245"
}
response = requests.get(url, headers=headers, params=params)
result = response.json()
if result['code'] == 'SUCCESS':
data = result['data']
print(f"Card Balance Information:")
print(f" Card Number: {data['card_number']}")
print(f" Available Balance: ${data['available_balance']}")
else:
print(f"Failed to query balance: {result}")
JavaScript (Node.js)
const axios = require('axios');
const url = 'https://gateway.ahrvo.network/card/issuance/api/issuing/card/v2/normal/balance';
const headers = {
'Accept': 'application/json',
'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
'x-api-key': 'YOUR_API_KEY'
};
const params = {
card_id: 'card201907021723076245'
};
axios.get(url, { headers, params })
.then(response => {
const result = response.data;
if (result.code === 'SUCCESS') {
const data = result.data;
console.log('Card Balance Information:');
console.log(` Card Number: ${data.card_number}`);
console.log(` Available Balance: $${data.available_balance}`);
}
})
.catch(error => {
console.error('Failed to query balance:', error.response.data);
});
Usage Notes
- Dedicated Funds Only: This endpoint only works for Dedicated Funds Cards
- Real-Time Balance: Returns the current available balance
- Currency: Balance is returned in the card's billing currency
- Masked Card Number: Card number is masked for security
- Balance Updates: Balance reflects recent transactions (may have slight delays during processing)
Common Use Cases
Check Card Balance Before Transaction
Verify sufficient balance before attempting a transaction:
def check_balance_before_transaction(card_id, transaction_amount):
"""
Check if card has sufficient balance for a transaction
"""
print(f"\nChecking balance for transaction of ${transaction_amount:.2f}...\n")
response = query_dedicated_funds_card_balance(card_id)
if response['code'] == 'SUCCESS':
data = response['data']
available_balance = float(data['available_balance'])
print(f"Card: {data['card_number']}")
print(f"Available Balance: ${available_balance:.2f}")
print(f"Transaction Amount: ${transaction_amount:.2f}")
if available_balance >= transaction_amount:
remaining = available_balance - transaction_amount
print(f"\n✓ Sufficient balance")
print(f" Balance after transaction: ${remaining:.2f}")
return {
'sufficient': True,
'available_balance': available_balance,
'remaining_after': remaining
}
else:
shortage = transaction_amount - available_balance
print(f"\n✗ Insufficient balance")
print(f" Shortage: ${shortage:.2f}")
print(f" Top-up required: ${shortage:.2f}")
return {
'sufficient': False,
'available_balance': available_balance,
'shortage': shortage
}
else:
print(f"Failed to check balance: {response}")
return {
'sufficient': False,
'error': response
}
# Example usage
check_result = check_balance_before_transaction('card201907021723076245', 500.00)
if check_result['sufficient']:
print("\nProceed with transaction")
else:
print(f"\nTop-up card with ${check_result['shortage']:.2f} before transaction")
Monitor Multiple Card Balances
Check balances for multiple Dedicated Funds Cards:
async function monitorCardBalances(cardIds) {
console.log('\n=== Card Balance Monitoring ===\n');
const balances = [];
let totalBalance = 0;
let lowBalanceCards = [];
for (const cardId of cardIds) {
try {
const response = await queryDedicatedFundsCardBalance(cardId);
if (response.code === 'SUCCESS') {
const data = response.data;
const balance = parseFloat(data.available_balance);
balances.push({
card_id: cardId,
card_number: data.card_number,
balance: balance
});
totalBalance += balance;
// Display card balance
console.log(`Card: ${data.card_number}`);
console.log(` Balance: $${balance.toFixed(2)}`);
// Check for low balance (less than $100)
if (balance < 100) {
console.log(` ⚠️ LOW BALANCE WARNING\n`);
lowBalanceCards.push({
card_id: cardId,
card_number: data.card_number,
balance: balance
});
} else if (balance < 500) {
console.log(` ⚡ Medium balance\n`);
} else {
console.log(` ✓ Good balance\n`);
}
} else {
console.log(`Card ${cardId}: Failed to query balance\n`);
}
} catch (error) {
console.error(`Error querying ${cardId}:`, error.message, '\n');
}
}
// Summary
console.log('=== Summary ===');
console.log(`Total Cards: ${balances.length}`);
console.log(`Total Balance: $${totalBalance.toFixed(2)}`);
console.log(`Average Balance: $${(totalBalance / balances.length).toFixed(2)}`);
if (lowBalanceCards.length > 0) {
console.log(`\n⚠️ Low Balance Alerts: ${lowBalanceCards.length} card(s)`);
lowBalanceCards.forEach(card => {
console.log(` • ${card.card_number}: $${card.balance.toFixed(2)}`);
});
}
return {
balances: balances,
total_balance: totalBalance,
low_balance_cards: lowBalanceCards
};
}
// Example usage
const cardIds = [
'card201907021723076245',
'card201907021723076246',
'card201907021723076247'
];
const report = await monitorCardBalances(cardIds);
Balance Alert System
Set up automated alerts for low balances:
def setup_balance_alerts(cards, thresholds):
"""
Monitor card balances and send alerts when below thresholds
Args:
cards: List of card IDs to monitor
thresholds: Dict with 'critical', 'warning', 'low' threshold amounts
"""
print("\n=== Balance Alert System ===\n")
print(f"Monitoring {len(cards)} card(s)")
print(f"Thresholds:")
print(f" Critical: Below ${thresholds['critical']:.2f}")
print(f" Warning: Below ${thresholds['warning']:.2f}")
print(f" Low: Below ${thresholds['low']:.2f}\n")
alerts = {
'critical': [],
'warning': [],
'low': [],
'normal': []
}
for card_id in cards:
try:
response = query_dedicated_funds_card_balance(card_id)
if response['code'] == 'SUCCESS':
data = response['data']
balance = float(data['available_balance'])
# Determine alert level
if balance <= thresholds['critical']:
level = 'critical'
icon = '🔴'
status = 'CRITICAL'
elif balance <= thresholds['warning']:
level = 'warning'
icon = '🟡'
status = 'WARNING'
elif balance <= thresholds['low']:
level = 'low'
icon = '🟠'
status = 'LOW'
else:
level = 'normal'
icon = '🟢'
status = 'NORMAL'
card_info = {
'card_id': card_id,
'card_number': data['card_number'],
'balance': balance,
'status': status
}
alerts[level].append(card_info)
print(f"{icon} {data['card_number']}: ${balance:.2f} - {status}")
# Send alerts for critical/warning
if level in ['critical', 'warning']:
send_balance_alert(card_info, level, thresholds)
except Exception as e:
print(f"✗ Error checking {card_id}: {e}")
# Summary
print(f"\n=== Alert Summary ===")
print(f"🔴 Critical: {len(alerts['critical'])} card(s)")
print(f"🟡 Warning: {len(alerts['warning'])} card(s)")
print(f"🟠 Low: {len(alerts['low'])} card(s)")
print(f"🟢 Normal: {len(alerts['normal'])} card(s)")
if alerts['critical']:
print(f"\n🚨 URGENT: {len(alerts['critical'])} card(s) require immediate top-up:")
for card in alerts['critical']:
print(f" • {card['card_number']}: ${card['balance']:.2f}")
return alerts
def send_balance_alert(card_info, level, thresholds):
"""Send alert notification (email/SMS/Slack)"""
# Implementation depends on your notification system
print(f" 📧 Alert sent for {card_info['card_number']}")
# Example usage
cards_to_monitor = [
'card201907021723076245',
'card201907021723076246',
'card201907021723076247'
]
thresholds = {
'critical': 50.00,
'warning': 100.00,
'low': 250.00
}
alerts = setup_balance_alerts(cards_to_monitor, thresholds)
Balance Reconciliation
Reconcile card balances against your internal records:
async function reconcileCardBalances(expectedBalances) {
console.log('\n=== Card Balance Reconciliation ===\n');
const discrepancies = [];
let totalDiscrepancy = 0;
for (const expected of expectedBalances) {
try {
const response = await queryDedicatedFundsCardBalance(expected.card_id);
if (response.code === 'SUCCESS') {
const data = response.data;
const actualBalance = parseFloat(data.available_balance);
const expectedBalance = parseFloat(expected.balance);
const difference = actualBalance - expectedBalance;
console.log(`Card: ${data.card_number}`);
console.log(` Expected: $${expectedBalance.toFixed(2)}`);
console.log(` Actual: $${actualBalance.toFixed(2)}`);
if (Math.abs(difference) > 0.01) { // Allow 1 cent tolerance
console.log(` ⚠️ DISCREPANCY: $${difference.toFixed(2)}\n`);
discrepancies.push({
card_id: expected.card_id,
card_number: data.card_number,
expected: expectedBalance,
actual: actualBalance,
difference: difference
});
totalDiscrepancy += Math.abs(difference);
} else {
console.log(` ✓ MATCHED\n`);
}
} else {
console.log(` ✗ Failed to query balance\n`);
}
} catch (error) {
console.error(`Error reconciling ${expected.card_id}:`, error.message, '\n');
}
}
// Summary
console.log('=== Reconciliation Summary ===');
console.log(`Total Cards Checked: ${expectedBalances.length}`);
console.log(`Discrepancies Found: ${discrepancies.length}`);
console.log(`Total Discrepancy Amount: $${totalDiscrepancy.toFixed(2)}`);
if (discrepancies.length > 0) {
console.log('\n⚠️ Cards with Discrepancies:');
discrepancies.forEach(disc => {
const sign = disc.difference > 0 ? '+' : '';
console.log(` • ${disc.card_number}: ${sign}$${disc.difference.toFixed(2)}`);
console.log(` Expected: $${disc.expected.toFixed(2)}, Actual: $${disc.actual.toFixed(2)}`);
});
console.log('\n💡 Next Steps:');
console.log(' 1. Review recent transactions for discrepant cards');
console.log(' 2. Check for pending transactions');
console.log(' 3. Update internal records if platform is correct');
console.log(' 4. Contact support if discrepancies persist');
} else {
console.log('\n✅ All balances match!');
}
return {
total_checked: expectedBalances.length,
discrepancies: discrepancies,
total_discrepancy: totalDiscrepancy
};
}
// Example usage
const expectedBalances = [
{ card_id: 'card201907021723076245', balance: '1468.87' },
{ card_id: 'card201907021723076246', balance: '2500.00' },
{ card_id: 'card201907021723076247', balance: '850.50' }
];
const reconciliation = await reconcileCardBalances(expectedBalances);
Generate Balance Report
Create a comprehensive balance report for all Dedicated Funds Cards:
def generate_balance_report(card_ids):
"""
Generate comprehensive balance report
"""
from datetime import datetime
print("\n" + "=" * 70)
print("DEDICATED FUNDS CARD BALANCE REPORT".center(70))
print("=" * 70)
print(f"Generated: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n")
balances = []
total_balance = 0
failed_queries = []
for card_id in card_ids:
try:
response = query_dedicated_funds_card_balance(card_id)
if response['code'] == 'SUCCESS':
data = response['data']
balance = float(data['available_balance'])
balances.append({
'card_id': card_id,
'card_number': data['card_number'],
'balance': balance
})
total_balance += balance
else:
failed_queries.append(card_id)
except Exception as e:
print(f"Error querying {card_id}: {e}")
failed_queries.append(card_id)
if not balances:
print("No balance data available\n")
return None
# Sort by balance (highest first)
balances.sort(key=lambda x: x['balance'], reverse=True)
# Display balances
print("Individual Card Balances:")
print("─" * 70)
for idx, card in enumerate(balances, 1):
percentage = (card['balance'] / total_balance * 100) if total_balance > 0 else 0
bar = '█' * int(percentage / 2)
print(f"{idx}. {card['card_number']}")
print(f" Balance: ${card['balance']:,.2f} ({percentage:.1f}%) {bar}")
# Statistics
print(f"\n{'Statistics'.center(70)}")
print("─" * 70)
print(f"Total Cards: {len(balances)}")
print(f"Total Balance: ${total_balance:,.2f}")
print(f"Average Balance: ${(total_balance / len(balances)):,.2f}")
print(f"Highest Balance: ${max(b['balance'] for b in balances):,.2f}")
print(f"Lowest Balance: ${min(b['balance'] for b in balances):,.2f}")
# Distribution
ranges = {
'$0-$100': 0,
'$100-$500': 0,
'$500-$1,000': 0,
'$1,000-$5,000': 0,
'$5,000+': 0
}
for card in balances:
balance = card['balance']
if balance < 100:
ranges['$0-$100'] += 1
elif balance < 500:
ranges['$100-$500'] += 1
elif balance < 1000:
ranges['$500-$1,000'] += 1
elif balance < 5000:
ranges['$1,000-$5,000'] += 1
else:
ranges['$5,000+'] += 1
print(f"\n{'Balance Distribution'.center(70)}")
print("─" * 70)
for range_name, count in ranges.items():
if count > 0:
bar = '█' * (count * 5)
print(f"{range_name.ljust(15)}: {count:2d} cards {bar}")
if failed_queries:
print(f"\n⚠️ Failed to query {len(failed_queries)} card(s):")
for card_id in failed_queries:
print(f" • {card_id}")
print("\n" + "=" * 70 + "\n")
return {
'total_cards': len(balances),
'total_balance': total_balance,
'average_balance': total_balance / len(balances) if balances else 0,
'balances': balances,
'distribution': ranges,
'failed_queries': failed_queries
}
# Example usage
card_list = [
'card201907021723076245',
'card201907021723076246',
'card201907021723076247',
'card201907021723076248',
'card201907021723076249'
]
report = generate_balance_report(card_list)
Balance Threshold Notification
Notify when balance crosses specific thresholds:
def monitor_balance_thresholds(card_id, thresholds):
"""
Check balance against multiple thresholds and notify
Args:
card_id: Card ID to monitor
thresholds: List of threshold amounts with actions
"""
response = query_dedicated_funds_card_balance(card_id)
if response['code'] == 'SUCCESS':
data = response['data']
balance = float(data['available_balance'])
print(f"\nCard: {data['card_number']}")
print(f"Current Balance: ${balance:.2f}\n")
triggered_actions = []
# Check each threshold
for threshold in sorted(thresholds, key=lambda x: x['amount'], reverse=True):
if balance <= threshold['amount']:
print(f"⚠️ Threshold Triggered: ${threshold['amount']:.2f}")
print(f" Action: {threshold['action']}")
print(f" Priority: {threshold.get('priority', 'NORMAL')}")
triggered_actions.append({
'threshold': threshold['amount'],
'action': threshold['action'],
'priority': threshold.get('priority', 'NORMAL'),
'current_balance': balance
})
if not triggered_actions:
print("✓ All thresholds OK")
else:
print(f"\n{len(triggered_actions)} action(s) triggered")
# Execute highest priority action
if triggered_actions:
highest_priority = max(triggered_actions,
key=lambda x: {'CRITICAL': 3, 'HIGH': 2, 'NORMAL': 1}.get(x['priority'], 0))
execute_threshold_action(card_id, highest_priority)
return {
'card_number': data['card_number'],
'balance': balance,
'triggered_actions': triggered_actions
}
else:
print(f"Failed to check balance: {response}")
return None
def execute_threshold_action(card_id, action):
"""Execute action based on threshold"""
print(f"\nExecuting Action: {action['action']}")
if action['action'] == 'AUTO_TOPUP':
print(f" • Initiating automatic top-up")
# Call top-up endpoint
elif action['action'] == 'NOTIFY_ADMIN':
print(f" • Sending notification to administrator")
# Send notification
elif action['action'] == 'FREEZE_CARD':
print(f" • Freezing card to prevent overdraft")
# Call freeze endpoint
# Example usage
thresholds = [
{'amount': 50.00, 'action': 'NOTIFY_ADMIN', 'priority': 'CRITICAL'},
{'amount': 100.00, 'action': 'AUTO_TOPUP', 'priority': 'HIGH'},
{'amount': 250.00, 'action': 'SEND_WARNING', 'priority': 'NORMAL'}
]
result = monitor_balance_thresholds('card201907021723076245', thresholds)
Best Practices
- Regular Monitoring: Check balances regularly to avoid insufficient funds
- Set Alerts: Implement automated alerts for low balance warnings
- Pre-Transaction Checks: Always verify balance before large transactions
- Reconciliation: Regularly reconcile platform balances with internal records
- Top-Up Automation: Consider automated top-ups for critical cards
- Dashboard Integration: Display balances in real-time on management dashboards
Understanding Dedicated Funds Cards
What are Dedicated Funds Cards?
- Each card has its own independent balance
- Not linked to budget accounts
- Balance must be topped up directly to the card
- Ideal for prepaid card programs, gift cards, or isolated spending
Dedicated vs Shared Funds Cards
| Feature | Dedicated Funds | Shared Funds |
|---|---|---|
| Balance Source | Individual card balance | Budget account |
| Spending Limits | Based on available balance | Configurable limits |
| Multiple Cards | Each card independent | Multiple cards share budget |
| Balance Query | This endpoint | Query budget balance |
| Top-Up | Top-up card directly | Top-up budget account |
Related Endpoints
- Top-up Dedicated Funds Card - Add funds to a card
- Withdraw Funds - Remove funds from a card
- Query Card Details - View complete card information
- Query Card Funding Orders - View top-up/withdrawal history
- Create a Card - Issue new Dedicated Funds Cards
Troubleshooting
Card Not Found (404)
- Cause: Invalid
card_idor card doesn't exist - Solution:
- Verify the card ID is correct
- Use Query All Cards to list available cards
- Check if card was deleted or cancelled
Wrong Card Type (400)
- Cause: Attempting to query balance of a Shared Funds Card
- Solution:
- This endpoint only works for Dedicated Funds Cards
- For Shared Funds Cards, query the budget account balance instead
- Use Query Card Details to check card type
Balance Discrepancy
- Cause: Recent transactions may not be immediately reflected
- Solution:
- Wait a few seconds and query again
- Check Query Card Funding Orders for recent transactions
- Verify all pending transactions have completed
Security Considerations
- Access Control: Restrict balance queries to authorized users only
- Data Privacy: Balance information is sensitive - handle accordingly
- Audit Logging: Log all balance queries for security auditing
- Rate Limiting: Implement reasonable query intervals
- Masked Card Numbers: Card numbers are masked but still handle carefully