Skip to main content

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

HeaderValueRequiredDescription
Acceptapplication/jsonYesContent type for the response
AuthorizationBearer {access_token}YesBearer token for authentication
x-api-keyAPI KeyYesAPI key for authentication

Query Parameters

ParameterTypeRequiredDescription
card_idstringYesA unique ID of the card

Response

Success Response (200 OK)

{
"code": "SUCCESS",
"data": {
"card_number": "5157********2686",
"available_balance": "1468.87"
}
}

Response Fields

FieldTypeDescription
codestringStatus string indicating the result. "SUCCESS" refers to a successful query
dataobjectResponse data object
data.card_numberstringMasked card number (e.g., 5157****8888)
data.available_balancestringAvailable balance of the Dedicated Funds Card (in USD)

Error Responses

  • 400 Bad Request: Invalid card_id or 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

FeatureDedicated FundsShared Funds
Balance SourceIndividual card balanceBudget account
Spending LimitsBased on available balanceConfigurable limits
Multiple CardsEach card independentMultiple cards share budget
Balance QueryThis endpointQuery budget balance
Top-UpTop-up card directlyTop-up budget account
  • 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_id or 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

Interactive API Explorer