Skip to content

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:

FieldUse
xaidThe account identifier. Key for every other call.
currencyRoll-up key.
displayNameWhat the finance team calls the account.
companyName, legalEntityRoll-up by entity.
typeIBAN or SCAN (UK sort code and account number).
statusOnly 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:

balancejson
{ "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

cash-position.jsjavascript
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.

Was this page helpful?
Suggest edits