Getting Started
Core Concepts
Resources
Account & Access
Data Domains
Help Center
Support
Fiskil’s API does not return historical balances directly—but you can reconstruct them by starting with the current balance and working backward through transaction history.
This guide shows how to generate a running balance after each transaction, using:
/v1/banking/balances
– to retrieve the current balance/v1/banking/transactions
– to retrieve all posted transactionsThis method is accurate to each individual transaction, not just by day.
To reconstruct a running balance timeline:
posting_date_time
descending.This produces an audit-accurate sequence of balance changes.
Example output:
[ { "transaction_id": "txn-1234", "posting_date_time": "2024-09-15T14:30:00Z", "amount": "-50.00", "balance_after": "950.00" }, { "transaction_id": "txn-1233", "posting_date_time": "2024-09-15T10:00:00Z", "amount": "-100.00", "balance_after": "1000.00" } ]
Use the /v1/banking/balances
endpoint:
GET /v1/banking/balances?end_user_id={end_user_id}&account_id={account_id}
This returns the most recent known balance for the account.
Example response:
{ "balances": [ { "account_id": "123456789", "current_balance": "-250.00", "currency": "AUD" } ] }
Use the /v1/banking/transactions
endpoint with a from
date:
GET /v1/banking/transactions?end_user_id={end_user_id}&account_id={account_id}&from=2024-09-02&status=POSTED
Retrieve all POSTED transactions and sort them in descending order by posting_date_time.
const fetch = require('node-fetch'); const ACCESS_TOKEN = 'YOUR_ACCESS_TOKEN'; const END_USER_ID = 'your_end_user_id'; const ACCOUNT_ID = 'your_account_id'; const BASE_URL = 'https://api.fiskil.com/v1'; const HEADERS = { 'Authorization': `Bearer ${ACCESS_TOKEN}`, 'Accept': 'application/json; charset=UTF-8', 'Content-Type': 'application/json; charset=UTF-8' }; // Fetch JSON helper async function fetchJSON(url) { const response = await fetch(url, { headers: HEADERS }); if (!response.ok) throw new Error(`HTTP ${response.status} - ${response.statusText}`); return response.json(); } // Step 1: Get current balance async function getCurrentBalance() { const url = `${BASE_URL}/banking/balances?end_user_id=${END_USER_ID}&account_id=${ACCOUNT_ID}`; const data = await fetchJSON(url); return parseFloat(data.balances?.[0]?.current_balance || '0'); } // Step 2: Get all posted transactions async function getAllPostedTransactions() { let transactions = []; let nextPage = null; do { const params = new URLSearchParams({ end_user_id: END_USER_ID, account_id: ACCOUNT_ID, status: 'POSTED', 'page[size]': 100 }); if (nextPage) params.set('page[after]', nextPage); const url = `${BASE_URL}/banking/transactions?${params.toString()}`; const data = await fetchJSON(url); transactions.push(...(data.transactions || [])); const match = data.links?.next?.match(/page\[after\]=([^&]+)/); nextPage = match?.[1] || null; } while (nextPage); // Sort transactions descending by posting_date_time return transactions.sort((a, b) => new Date(b.posting_date_time) - new Date(a.posting_date_time) ); } // Step 3: Build per-transaction balance timeline async function getTransactionBalanceTimeline() { const transactions = await getAllPostedTransactions(); let balance = await getCurrentBalance(); const timeline = transactions.map(tx => { const txAmount = parseFloat(tx.amount); const entry = { transaction_id: tx.transaction_id, posting_date_time: tx.posting_date_time, amount: tx.amount, balance_after: balance.toFixed(2) }; balance -= txAmount; return entry; }); return timeline; } // Run and display the timeline getTransactionBalanceTimeline() .then(timeline => { console.log("Transaction-level balance timeline:"); console.table(timeline); }) .catch(console.error);
Per-transaction precision
Each balance entry corresponds directly to a specific posted transaction, providing an accurate ledger-style timeline.
Extendable structure
You can enrich each timeline entry with additional transaction fields such as:
description
merchant_name
category.primary_category
reference
This can make the balance timeline more informative for audit trails or UIs.
Derive daily or monthly snapshots
If needed, you can group transactions and extract the balance_after
of the last transaction per day or per month to generate high-level trends.
Timezone handling
All posting_date_time
values from the Fiskil API are in UTC. If you're displaying balances in a user-facing product, make sure to adjust for the user's local timezone where appropriate.
Currency consideration
This implementation assumes a single currency per account. If the account includes multi-currency purses
, you'll need to run this logic per currency.
Performance
For high-volume accounts, consider caching results or running this logic as a background job if the full ledger is long. You can also limit by date using the from
/to
parameters on /transactions
to reduce API load.
Was this page helpful?