Skip to main content

Fetch a Balance Entry

Retrieve the details of a specific Balance Entry. A Balance Entry reflects a change to an application's Balance due to a Transfer or a Balance Adjustment (i.e., "top-up"). Each entry provides a complete audit trail of what caused the balance change and when it was posted.

Use Cases

1. Get Entry Details

Fetch a specific balance entry:

curl https://api.ahrvo.network/payments/na/balance_entries/balance_entry_i5YzFZYEh6CoCrN2zqgPdW \
-u username:password \
-H "Content-Type: application/json"

2. Verify Balance Adjustment

Confirm a balance adjustment was posted correctly:

async function verifyBalanceAdjustment(entryId, expectedAmount) {
const response = await fetch(
`https://api.ahrvo.network/payments/na/balance_entries/${entryId}`,
{
headers: {
'Authorization': 'Basic ' + btoa('username:password'),
'Content-Type': 'application/json'
}
}
);

const entry = await response.json();

const verification = {
entry_id: entry.id,
expected_amount: expectedAmount,
actual_amount: entry.amount,
matches: entry.amount === expectedAmount,
state: entry.state,
type: entry.type,
entity_type: entry.entity_type,
entity_id: entry.entity_id
};

if (!verification.matches) {
console.error('Amount mismatch:', verification);
} else if (entry.state !== 'SUCCEEDED') {
console.warn('Entry not successful:', entry.state);
} else {
console.log('✅ Balance adjustment verified');
}

return verification;
}

3. Track Entry to Source Transaction

Trace a balance entry back to its originating transaction:

async function traceEntryToSource(entryId) {
const response = await fetch(
`https://api.ahrvo.network/payments/na/balance_entries/${entryId}`,
{
headers: {
'Authorization': 'Basic ' + btoa('username:password')
}
}
);

const entry = await response.json();

const trace = {
entry_id: entry.id,
created_at: entry.created_at,
amount: `$${(entry.amount / 100).toFixed(2)}`,
type: entry.type,
source: {
entity_type: entry.entity_type,
entity_id: entry.entity_id
},
application: entry.linked_to,
description: entry.description,
state: entry.state,
posted_at: entry.posted_at,
estimated_posted_date: entry.estimated_posted_date
};

console.log('Entry Trace:', trace);

// Fetch the source entity if needed
if (entry.entity_type === 'BALANCE_ADJUSTMENT') {
const adjustment = await fetchBalanceAdjustment(entry.entity_id);
trace.source_details = adjustment;
} else if (entry.entity_type === 'TRANSFER') {
const transfer = await fetchTransfer(entry.entity_id);
trace.source_details = transfer;
}

return trace;
}

4. Verify Posting Date

Check when an entry was actually posted:

async function getPostingDetails(entryId) {
const response = await fetch(
`https://api.ahrvo.network/payments/na/balance_entries/${entryId}`,
{
headers: {
'Authorization': 'Basic ' + btoa('username:password')
}
}
);

const entry = await response.json();

const created = new Date(entry.created_at);
const estimated = new Date(entry.estimated_posted_date);
const posted = new Date(entry.posted_at);

const details = {
entry_id: entry.id,
created_at: created.toISOString(),
estimated_posted_date: estimated.toISOString(),
posted_at: posted.toISOString(),
posting_delay_ms: posted - created,
posting_delay_formatted: formatDuration(posted - created),
was_early: posted < estimated,
was_late: posted > estimated,
variance_ms: posted - estimated
};

return details;
}

function formatDuration(ms) {
const seconds = Math.floor(ms / 1000);
const minutes = Math.floor(seconds / 60);
const hours = Math.floor(minutes / 60);
const days = Math.floor(hours / 24);

if (days > 0) return `${days} day${days > 1 ? 's' : ''}`;
if (hours > 0) return `${hours} hour${hours > 1 ? 's' : ''}`;
if (minutes > 0) return `${minutes} minute${minutes > 1 ? 's' : ''}`;
return `${seconds} second${seconds > 1 ? 's' : ''}`;
}

5. Audit Wire Transfer Details

For wire transfers, extract additional reference information:

async function auditWireTransfer(entryId) {
const response = await fetch(
`https://api.ahrvo.network/payments/na/balance_entries/${entryId}`,
{
headers: {
'Authorization': 'Basic ' + btoa('username:password')
}
}
);

const entry = await response.json();

if (entry.type !== 'BALANCE_TOP_UP_WIRE') {
throw new Error('Entry is not a wire transfer');
}

const audit = {
entry_id: entry.id,
amount: entry.amount,
wire_details: entry.wire_details,
external_reference: entry.wire_details?.external_reference_number,
created_at: entry.created_at,
posted_at: entry.posted_at,
entity_id: entry.entity_id,
description: entry.description
};

console.log('Wire Transfer Audit:', audit);

return audit;
}

Path Parameters

ParameterTypeRequiredDescription
balance_entry_idstringYesThe unique ID of the Balance Entry

Response Fields

FieldTypeDescription
idstringUnique identifier for the balance entry
created_atstringISO 8601 timestamp of creation
updated_atstringISO 8601 timestamp of last update
amountintegerAmount of the balance entry (in cents)
created_bystringEntity that created the entry (e.g., "SYSTEM")
currencystringCurrency code (e.g., "USD")
descriptionstringDescription of the balance entry
entity_idstringID of the entity that caused the balance entry
entity_typestringType of entity (BALANCE_ADJUSTMENT, TRANSFER, etc.)
estimated_posted_datestringEstimated date when entry will be posted
linked_tostringID of the linked Application
linked_typestringType of linked entity (e.g., "APPLICATION")
parent_balance_entry_idstringID of parent entry if applicable
posted_atstringActual date when entry was posted
statestringState of the balance entry (e.g., "SUCCEEDED")
tagsobjectCustom metadata
transaction_datestringDate of the transaction
typestringType of balance entry (BALANCE_TOP_UP_ACH, PUSH_TO_CARD, etc.)
wire_detailsobjectWire transfer details (if applicable)
wire_details.external_reference_numberstringExternal reference for wire transfers

Entry Types

Common balance entry types include:

  • BALANCE_TOP_UP_ACH: ACH balance top-up (1-3 days)
  • BALANCE_TOP_UP_WIRE: Wire balance top-up (same/next day)
  • PUSH_TO_CARD: Funds pushed to a card
  • TRANSFER: Standard transfer
  • FEE: Platform or processing fee
  • REFUND: Refund transaction
  • PAYOUT: Merchant payout

Best Practices

1. Use for Audit Trails

Balance entries provide complete audit trails:

async function buildAuditTrail(entryId) {
const response = await fetch(
`https://api.ahrvo.network/payments/na/balance_entries/${entryId}`,
{
headers: {
'Authorization': 'Basic ' + btoa('username:password')
}
}
);

const entry = await response.json();

const auditRecord = {
audit_timestamp: new Date().toISOString(),
entry: {
id: entry.id,
type: entry.type,
amount: entry.amount,
currency: entry.currency,
state: entry.state
},
source: {
entity_type: entry.entity_type,
entity_id: entry.entity_id,
created_by: entry.created_by
},
timing: {
created_at: entry.created_at,
estimated_posted: entry.estimated_posted_date,
actual_posted: entry.posted_at,
transaction_date: entry.transaction_date
},
application: {
id: entry.linked_to,
type: entry.linked_type
},
metadata: {
description: entry.description,
tags: entry.tags,
parent_entry: entry.parent_balance_entry_id
}
};

// Store audit record
await storeAuditRecord('balance_entry', auditRecord);

return auditRecord;
}

2. Verify Entry State

Always check if the entry succeeded:

async function ensureEntrySucceeded(entryId) {
const response = await fetch(
`https://api.ahrvo.network/payments/na/balance_entries/${entryId}`,
{
headers: {
'Authorization': 'Basic ' + btoa('username:password')
}
}
);

const entry = await response.json();

if (entry.state !== 'SUCCEEDED') {
throw new Error(`Balance entry ${entryId} in state: ${entry.state}`);
}

return entry;
}

Track relationship between entries and source:

class BalanceEntryTracker {
constructor() {
this.entryMap = new Map();
}

async recordEntry(entryId) {
const response = await fetch(
`https://api.ahrvo.network/payments/na/balance_entries/${entryId}`,
{
headers: {
'Authorization': 'Basic ' + btoa('username:password')
}
}
);

const entry = await response.json();

const record = {
entry_id: entry.id,
entity_type: entry.entity_type,
entity_id: entry.entity_id,
amount: entry.amount,
posted_at: entry.posted_at,
type: entry.type
};

this.entryMap.set(entry.id, record);

return record;
}

getEntriesByEntity(entityId) {
return Array.from(this.entryMap.values())
.filter(e => e.entity_id === entityId);
}
}

4. Handle Wire Transfer References

Extract wire reference numbers when available:

async function getWireReference(entryId) {
const response = await fetch(
`https://api.ahrvo.network/payments/na/balance_entries/${entryId}`,
{
headers: {
'Authorization': 'Basic ' + btoa('username:password')
}
}
);

const entry = await response.json();

if (!entry.wire_details || !entry.wire_details.external_reference_number) {
return null;
}

return {
entry_id: entry.id,
wire_reference: entry.wire_details.external_reference_number,
amount: entry.amount,
posted_at: entry.posted_at
};
}

5. Monitor Posting Delays

Track how long entries take to post:

async function analyzePostingDelay(entryId) {
const response = await fetch(
`https://api.ahrvo.network/payments/na/balance_entries/${entryId}`,
{
headers: {
'Authorization': 'Basic ' + btoa('username:password')
}
}
);

const entry = await response.json();

const created = new Date(entry.created_at);
const posted = new Date(entry.posted_at);
const estimated = new Date(entry.estimated_posted_date);

const analysis = {
entry_id: entry.id,
type: entry.type,
actual_delay: posted - created,
estimated_delay: estimated - created,
variance: posted - estimated,
was_on_time: Math.abs(posted - estimated) < 3600000, // Within 1 hour
delay_formatted: formatDuration(posted - created)
};

if (!analysis.was_on_time) {
console.warn('Entry posted outside estimated window:', analysis);
}

return analysis;
}

Common Workflows

Reconciliation Workflow

async function reconcileBalanceEntry(entryId, expectedValues) {
const response = await fetch(
`https://api.ahrvo.network/payments/na/balance_entries/${entryId}`,
{
headers: {
'Authorization': 'Basic ' + btoa('username:password')
}
}
);

const entry = await response.json();

const reconciliation = {
entry_id: entry.id,
checks: [],
passed: true
};

// Check amount
if (expectedValues.amount && entry.amount !== expectedValues.amount) {
reconciliation.passed = false;
reconciliation.checks.push({
field: 'amount',
expected: expectedValues.amount,
actual: entry.amount,
passed: false
});
}

// Check entity
if (expectedValues.entity_id && entry.entity_id !== expectedValues.entity_id) {
reconciliation.passed = false;
reconciliation.checks.push({
field: 'entity_id',
expected: expectedValues.entity_id,
actual: entry.entity_id,
passed: false
});
}

// Check state
if (entry.state !== 'SUCCEEDED') {
reconciliation.passed = false;
reconciliation.checks.push({
field: 'state',
expected: 'SUCCEEDED',
actual: entry.state,
passed: false
});
}

return reconciliation;
}

Entry Verification After Adjustment

async function verifyAdjustmentPosted(balanceAdjustmentId) {
// Note: You'd typically get the entry ID from the balance adjustment response
// or by listing entries and filtering by entity_id

const entries = await listBalanceEntries(balanceId);
const entry = entries.find(e =>
e.entity_id === balanceAdjustmentId &&
e.entity_type === 'BALANCE_ADJUSTMENT'
);

if (!entry) {
throw new Error('No entry found for adjustment');
}

const response = await fetch(
`https://api.ahrvo.network/payments/na/balance_entries/${entry.id}`,
{
headers: {
'Authorization': 'Basic ' + btoa('username:password')
}
}
);

const fullEntry = await response.json();

if (fullEntry.state !== 'SUCCEEDED') {
throw new Error(`Adjustment not yet posted: ${fullEntry.state}`);
}

console.log('✅ Balance adjustment posted successfully');
return fullEntry;
}

Interactive API Reference