Accounts
Building a live cash position across accounts
Last updated 14 September 2026
The first thing treasury wants is one number per currency, and then one per entity. Two endpoints give you everything you need.
Step 1: list the accounts
GET /accounts returns every account the credentials can see. The fields you care about:
| Field | Use |
|---|---|
| xaid | The account identifier. Key for every other call. |
| currency | Roll-up key. |
| displayName | What the finance team calls the account. |
| companyName, legalEntity | Roll-up by entity. |
| type | IBAN or SCAN (UK sort code and account number). |
| status | Only include ACTIVE accounts. |
Cache this list. Accounts change rarely; refresh it hourly or on a webhook, not per request.
Step 2: fetch each balance
GET /account/{xaid}/balance:
{ "currency": "EUR", "balance": 250000, "availableBalance": 238500, "pendingBalance": 11500 }- availableBalance is what can be spent now.
- pendingBalance is committed but not settled: outgoing payments awaiting approval or in flight.
- balance is the ledger balance.
Treasury usually wants available. Compliance and audit usually want ledger. Show both.
Step 3: roll up
const accounts = (await listAll('/accounts', token)).filter(a => a.status === 'ACTIVE');
const balances = await Promise.all(
accounts.map(async a => ({
...a,
...(await getJson(`/account/${a.xaid}/balance`, token)),
})),
);
const byCurrency = {};
const byEntity = {};
for (const b of balances) {
byCurrency[b.currency] = (byCurrency[b.currency] ?? 0) + b.availableBalance;
const key = `${b.companyName} ${b.currency}`;
byEntity[key] = (byEntity[key] ?? 0) + b.availableBalance;
}Keep the per-account rows too. The roll-up answers "how much EUR do we have"; the rows answer "which account is short".
How often to poll
Balances change on every transaction, but a cash position does not need to be tick-accurate. Every five minutes during business hours is plenty for a dashboard. If you need to react to a specific inbound payment, use a TransactionReceived webhook rather than polling faster. See Subscribing to webhooks.
Balances are per account, not per entity
There is no group balance endpoint. Sum available balances across the accounts you fetched, and be explicit in the UI about which accounts are included.