Skip to main content
GET /v3/fx/balances returns your organization’s funds in two parts: an aggregate for the whole organization, and one row per currency in balances. Each part answers a different question, and each carries amounts that mean different things. Read this page before you gate a trade or withdrawal on a balance.
totalBalance and withdrawableBalance are not the same number, and neither one is “what you can trade”. Check withdrawableBalance for the currency you are selling, and use aggregate as the ceiling across all currencies.

The response

A successful response wraps the balances in data. There is no pagination: the response is the complete set, one row per currency you hold.
cURL
Amounts are decimal strings. Parse them as decimals, never as floats. See Amounts.

Aggregate

aggregate is your organization’s net equity across every currency, converted to USD. It is the ceiling on what you can withdraw in total. Read aggregate rather than deriving it. It is converted across currencies by OpenFX, so adding the per-currency rows yourself will not reproduce it.

Per-currency balances

Each entry in balances describes one currency you hold.

Withdrawable and total

The two amounts relate in one of three ways. In the example above, USD shows 50000.00 withdrawable of 60000.00 total, so 10000.00 is reserved. EUR shows a negative total with 0 withdrawable, meaning the organization owes a settlement in EUR. A negative totalBalance in one currency does not make the whole response negative. aggregate nets your currencies, so check it separately.

What changes a balance

Check a balance before you act

Balances are real-time, so the response is a snapshot. Two checks use it.
  • Before a trade. Compare the sell amount against withdrawableBalance for the sell currency. OpenFX checks the sell-side balance at execution, and a shortfall returns 409 TRADE_INSUFFICIENT_BALANCE with requiredAmount and availableAmount in error.details.
  • Before a withdrawal. Compare the amount against withdrawableBalance for that currency. A shortfall returns 409 WITHDRAWAL_INSUFFICIENT_BALANCE.
A balance can change between your read and your write, so treat the check as a guard and handle the error on the write. To reconcile, re-read balances when a deposit or trade webhook arrives rather than polling on a timer.

Common mistakes

  • Gating on totalBalance. It includes reserved amounts. Use withdrawableBalance to decide what you can spend.
  • Summing the rows to get the aggregate. The rows are in different currencies. Read aggregate.
  • Treating a negative totalBalance as an error. It means you owe a settlement in that currency. withdrawableBalance is 0 for it.
  • Expecting a row for every currency. The response lists only currencies you hold.
  • Parsing amounts as floats. Use a decimal type.

What’s next

Trades

When a trade moves funds, and what you can do while it waits.

Settlement models

Deposits, balances, and withdrawals in one flow.

Exposure

Exposure-limit usage, separate from your balances.

Amounts

Decimal strings and precision rules.