Skip to main content

Query Budget Account Balance

Overview

Use this endpoint to query the balance of all budget accounts. This returns the available balance, currency, budget ID, and budget name for each account. This is essential for monitoring spending, checking available funds, and making funding decisions.

NOTE: This API is offered on a client-by-client approval basis. Speak to your account manager to check eligibility.

Resource Access

Production (api.ahrvo.network)

GET https://api.ahrvo.network/card/issuance/api/issuing/budget/v2/balance/all

Staging (gateway.ahrvo.network)

GET https://gateway.ahrvo.network/card/issuance/api/issuing/budget/v2/balance/all

Request Headers

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

Response

Success Response (200 OK)

{
"code": "SUCCESS",
"data": [
{
"budget_id": "ci202507232016182661",
"budget_name": "Marketing Department Budget",
"balance": "45250.75",
"currency": "USD"
},
{
"budget_id": "ci202507232016182662",
"budget_name": "Engineering Team Budget",
"balance": "78900.00",
"currency": "USD"
},
{
"budget_id": "ci202507232016182663",
"budget_name": "Travel Expenses",
"balance": "12500.50",
"currency": "USD"
}
]
}

Response Fields

FieldTypeDescription
codestringStatus string indicating the result. "SUCCESS" refers to a successful query
dataarrayArray of budget account balance information

Budget Balance Object

FieldTypeDescription
budget_idstringA unique ID of the budget account
budget_namestringThe name of the budget account
balancestringThe available remaining balance of the budget account
currencystringCurrency of the budget account (e.g., USD, EUR, GBP)

Error Responses

  • 401 Unauthorized: Invalid or missing authentication token
  • 403 Forbidden: Card issuance feature not enabled for this account
  • 404 Not Found: No budget accounts exist

Code Examples

cURL

curl -X GET \
'https://gateway.ahrvo.network/card/issuance/api/issuing/budget/v2/balance/all' \
-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/budget/v2/balance/all"
headers = {
"Accept": "application/json",
"Authorization": "Bearer YOUR_ACCESS_TOKEN",
"x-api-key": "YOUR_API_KEY"
}

response = requests.get(url, headers=headers)
result = response.json()

if result['code'] == 'SUCCESS':
print("Budget Account Balances:")
print("-" * 80)

total_balance = 0
for budget in result['data']:
balance = float(budget['balance'])
total_balance += balance

print(f"Budget: {budget['budget_name']}")
print(f" ID: {budget['budget_id']}")
print(f" Balance: {budget['currency']} {balance:,.2f}")
print("-" * 80)

print(f"Total Balance: USD {total_balance:,.2f}")
else:
print(f"Failed to query balances: {result}")

JavaScript (Node.js)

const axios = require('axios');

const url = 'https://gateway.ahrvo.network/card/issuance/api/issuing/budget/v2/balance/all';
const headers = {
'Accept': 'application/json',
'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
'x-api-key': 'YOUR_API_KEY'
};

axios.get(url, { headers })
.then(response => {
const result = response.data;

if (result.code === 'SUCCESS') {
console.log('Budget Account Balances:');
console.log('-'.repeat(80));

let totalBalance = 0;
result.data.forEach(budget => {
const balance = parseFloat(budget.balance);
totalBalance += balance;

console.log(`Budget: ${budget.budget_name}`);
console.log(` ID: ${budget.budget_id}`);
console.log(` Balance: ${budget.currency} ${balance.toLocaleString('en-US', { minimumFractionDigits: 2 })}`);
console.log('-'.repeat(80));
});

console.log(`Total Balance: USD ${totalBalance.toLocaleString('en-US', { minimumFractionDigits: 2 })}`);
}
})
.catch(error => {
console.error('Failed to query balances:', error.response.data);
});

Usage Notes

  • All Budgets: This endpoint returns all budget accounts associated with your account
  • Real-Time Data: Balance information reflects the current available funds
  • Currency: Each budget has its own currency designation
  • Empty Result: If no budget accounts exist, you'll receive an empty array
  • Monitoring: Use this endpoint regularly to monitor budget status

Common Use Cases

Dashboard Overview

Display all budget balances in an admin dashboard:

def get_budget_overview():
"""
Get a comprehensive overview of all budget accounts
"""
response = query_budget_balance()

if response['code'] != 'SUCCESS':
return None

budgets = response['data']

# Calculate statistics
total_balance = sum(float(b['balance']) for b in budgets)
budget_count = len(budgets)
avg_balance = total_balance / budget_count if budget_count > 0 else 0

# Find low balance budgets (less than $1000)
low_balance_budgets = [
b for b in budgets
if float(b['balance']) < 1000
]

# Find highest balance budget
highest_budget = max(budgets, key=lambda b: float(b['balance'])) if budgets else None

return {
'total_budgets': budget_count,
'total_balance': total_balance,
'average_balance': avg_balance,
'low_balance_count': len(low_balance_budgets),
'low_balance_budgets': low_balance_budgets,
'highest_budget': highest_budget,
'all_budgets': budgets
}

# Example usage
overview = get_budget_overview()
print(f"Total Budgets: {overview['total_budgets']}")
print(f"Total Balance: ${overview['total_balance']:,.2f}")
print(f"Average Balance: ${overview['average_balance']:,.2f}")
print(f"Budgets with Low Balance: {overview['low_balance_count']}")

Low Balance Alerts

Monitor budgets and alert when balance is low:

async function checkLowBalanceBudgets(threshold = 5000) {
try {
const response = await queryBudgetBalance();

if (response.code !== 'SUCCESS') {
throw new Error('Failed to query balances');
}

const lowBalanceBudgets = response.data.filter(budget => {
return parseFloat(budget.balance) < threshold;
});

if (lowBalanceBudgets.length > 0) {
console.log(`⚠️ ${lowBalanceBudgets.length} budget(s) below threshold of $${threshold}`);

for (const budget of lowBalanceBudgets) {
console.log(` - ${budget.budget_name}: ${budget.currency} ${budget.balance}`);

// Send alert notification
await sendLowBalanceAlert({
budget_id: budget.budget_id,
budget_name: budget.budget_name,
current_balance: budget.balance,
threshold: threshold
});
}
} else {
console.log('✓ All budgets are above the threshold');
}

return lowBalanceBudgets;
} catch (error) {
console.error('Error checking low balance budgets:', error);
throw error;
}
}

// Run every hour
setInterval(() => checkLowBalanceBudgets(5000), 60 * 60 * 1000);

Budget Allocation Report

Generate a report showing budget allocation and utilization:

def generate_budget_allocation_report():
"""
Generate a detailed report of budget allocation
"""
response = query_budget_balance()

if response['code'] != 'SUCCESS':
print("Failed to retrieve budget data")
return

budgets = response['data']

if not budgets:
print("No budget accounts found")
return

# Calculate total and percentages
total_balance = sum(float(b['balance']) for b in budgets)

print("=" * 100)
print("BUDGET ALLOCATION REPORT")
print("=" * 100)
print(f"Generated: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
print(f"Total Number of Budgets: {len(budgets)}")
print(f"Total Balance: USD {total_balance:,.2f}")
print("=" * 100)
print()

# Sort by balance descending
sorted_budgets = sorted(budgets, key=lambda b: float(b['balance']), reverse=True)

print(f"{'Budget Name':<40} {'Budget ID':<25} {'Balance':>15} {'% of Total':>10}")
print("-" * 100)

for budget in sorted_budgets:
balance = float(budget['balance'])
percentage = (balance / total_balance * 100) if total_balance > 0 else 0

print(f"{budget['budget_name']:<40} {budget['budget_id']:<25} "
f"{budget['currency']} {balance:>12,.2f} {percentage:>9.1f}%")

print("=" * 100)

# Return structured data
return {
'generated_at': datetime.now().isoformat(),
'total_budgets': len(budgets),
'total_balance': total_balance,
'budgets': sorted_budgets
}

# Example usage
report = generate_budget_allocation_report()

Find Specific Budget Balance

Look up a specific budget by name or ID:

async function findBudgetBalance(searchTerm) {
try {
const response = await queryBudgetBalance();

if (response.code !== 'SUCCESS') {
throw new Error('Failed to query balances');
}

// Search by budget ID or name
const budget = response.data.find(b =>
b.budget_id === searchTerm ||
b.budget_name.toLowerCase().includes(searchTerm.toLowerCase())
);

if (budget) {
console.log('Budget Found:');
console.log(` Name: ${budget.budget_name}`);
console.log(` ID: ${budget.budget_id}`);
console.log(` Balance: ${budget.currency} ${parseFloat(budget.balance).toLocaleString()}`);
return budget;
} else {
console.log(`Budget not found: ${searchTerm}`);
return null;
}
} catch (error) {
console.error('Error finding budget:', error);
throw error;
}
}

// Example usage
const budget = await findBudgetBalance('Marketing');

Budget Health Score

Calculate a health score for each budget:

def calculate_budget_health_scores():
"""
Calculate health scores for all budgets based on balance levels
"""
response = query_budget_balance()

if response['code'] != 'SUCCESS':
return None

budgets = response['data']
budget_health = []

for budget in budgets:
balance = float(budget['balance'])

# Calculate health score (0-100)
if balance >= 50000:
score = 100
status = 'Excellent'
elif balance >= 25000:
score = 80
status = 'Good'
elif balance >= 10000:
score = 60
status = 'Fair'
elif balance >= 5000:
score = 40
status = 'Low'
else:
score = 20
status = 'Critical'

budget_health.append({
'budget_id': budget['budget_id'],
'budget_name': budget['budget_name'],
'balance': balance,
'currency': budget['currency'],
'health_score': score,
'health_status': status
})

# Sort by health score
budget_health.sort(key=lambda x: x['health_score'])

return budget_health

# Example usage
health_scores = calculate_budget_health_scores()
for budget in health_scores:
print(f"{budget['budget_name']}: {budget['health_status']} "
f"(Score: {budget['health_score']}, Balance: ${budget['balance']:,.2f})")

Export Budget Data

Export budget balances to CSV or JSON:

import csv
import json
from datetime import datetime

def export_budget_balances(format='csv', filename=None):
"""
Export budget balance data to file
"""
response = query_budget_balance()

if response['code'] != 'SUCCESS':
print("Failed to retrieve budget data")
return None

budgets = response['data']

if not filename:
timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
filename = f"budget_balances_{timestamp}.{format}"

if format == 'csv':
with open(filename, 'w', newline='') as csvfile:
fieldnames = ['budget_id', 'budget_name', 'balance', 'currency']
writer = csv.DictWriter(csvfile, fieldnames=fieldnames)

writer.writeheader()
for budget in budgets:
writer.writerow(budget)

print(f"Budget balances exported to {filename}")

elif format == 'json':
export_data = {
'exported_at': datetime.now().isoformat(),
'total_budgets': len(budgets),
'budgets': budgets
}

with open(filename, 'w') as jsonfile:
json.dump(export_data, jsonfile, indent=2)

print(f"Budget balances exported to {filename}")

return filename

# Example usage
export_budget_balances(format='csv')
export_budget_balances(format='json')

Real-Time Balance Monitoring

Set up continuous monitoring with notifications:

class BudgetMonitor {
constructor(checkInterval = 300000) { // 5 minutes default
this.checkInterval = checkInterval;
this.previousBalances = new Map();
this.isRunning = false;
}

async start() {
console.log('Starting budget monitor...');
this.isRunning = true;
await this.checkBalances();

this.intervalId = setInterval(() => {
if (this.isRunning) {
this.checkBalances();
}
}, this.checkInterval);
}

stop() {
console.log('Stopping budget monitor...');
this.isRunning = false;
if (this.intervalId) {
clearInterval(this.intervalId);
}
}

async checkBalances() {
try {
const response = await queryBudgetBalance();

if (response.code !== 'SUCCESS') {
console.error('Failed to query balances');
return;
}

for (const budget of response.data) {
const currentBalance = parseFloat(budget.balance);
const previousBalance = this.previousBalances.get(budget.budget_id);

if (previousBalance !== undefined) {
const change = currentBalance - previousBalance;

if (change !== 0) {
console.log(`Balance change detected for ${budget.budget_name}`);
console.log(` Previous: ${budget.currency} ${previousBalance.toFixed(2)}`);
console.log(` Current: ${budget.currency} ${currentBalance.toFixed(2)}`);
console.log(` Change: ${budget.currency} ${change.toFixed(2)}`);

// Send notification if change is significant
if (Math.abs(change) > 1000) {
await this.sendBalanceChangeAlert(budget, previousBalance, currentBalance, change);
}
}
}

// Update stored balance
this.previousBalances.set(budget.budget_id, currentBalance);
}
} catch (error) {
console.error('Error checking balances:', error);
}
}

async sendBalanceChangeAlert(budget, previousBalance, currentBalance, change) {
// Implement your notification logic here
console.log(`🔔 Alert: Significant balance change for ${budget.budget_name}`);
}
}

// Example usage
const monitor = new BudgetMonitor(300000); // Check every 5 minutes
monitor.start();

// Stop monitoring when needed
// monitor.stop();

Best Practices

  • Regular Monitoring: Check balances regularly to ensure sufficient funds
  • Alert Thresholds: Set up alerts for low balance conditions
  • Data Caching: Cache balance data appropriately but refresh regularly
  • Error Handling: Implement proper error handling for failed queries
  • Logging: Log balance checks for audit purposes
  • Dashboard Integration: Display balance information in administrative dashboards
  • Create Budget Account - Create new budget accounts
  • Transfer to Budget - Add funds to a budget account
  • Withdraw from Budget - Remove funds from a budget account
  • Query Budget Details - Get detailed information about a specific budget
  • Query Transaction History - View transaction history for a budget

Troubleshooting

Empty Data Array

  • Cause: No budget accounts have been created yet
  • Solution: Create budget accounts first using the Create Budget Account endpoint

Unauthorized (401)

  • Cause: Invalid or expired authentication token
  • Solution: Refresh your access token and try again

Forbidden (403)

  • Cause: Card issuance feature not enabled for your account
  • Solution: Contact your account manager to enable card issuance

Stale Balance Data

  • Cause: Cached or delayed data
  • Solution:
    • The API returns real-time data
    • Clear any client-side caching
    • Verify recent transactions have completed processing

Performance Considerations

  • Response Size: The response size grows with the number of budget accounts
  • Polling Frequency: Don't poll too frequently; implement reasonable intervals
  • Data Processing: Process the response efficiently for large numbers of budgets
  • Caching Strategy: Implement appropriate caching with reasonable TTL

Interactive API Explorer