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
| Parameter | Type | Required | Description |
|---|---|---|---|
balance_entry_id | string | Yes | The unique ID of the Balance Entry |
Response Fields
| Field | Type | Description |
|---|---|---|
id | string | Unique identifier for the balance entry |
created_at | string | ISO 8601 timestamp of creation |
updated_at | string | ISO 8601 timestamp of last update |
amount | integer | Amount of the balance entry (in cents) |
created_by | string | Entity that created the entry (e.g., "SYSTEM") |
currency | string | Currency code (e.g., "USD") |
description | string | Description of the balance entry |
entity_id | string | ID of the entity that caused the balance entry |
entity_type | string | Type of entity (BALANCE_ADJUSTMENT, TRANSFER, etc.) |
estimated_posted_date | string | Estimated date when entry will be posted |
linked_to | string | ID of the linked Application |
linked_type | string | Type of linked entity (e.g., "APPLICATION") |
parent_balance_entry_id | string | ID of parent entry if applicable |
posted_at | string | Actual date when entry was posted |
state | string | State of the balance entry (e.g., "SUCCEEDED") |
tags | object | Custom metadata |
transaction_date | string | Date of the transaction |
type | string | Type of balance entry (BALANCE_TOP_UP_ACH, PUSH_TO_CARD, etc.) |
wire_details | object | Wire transfer details (if applicable) |
wire_details.external_reference_number | string | External 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;
}
3. Link Entries to Source Transactions
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;
}