Overview

Every OpenFX account maintains a set of balance entries that reflect its current financial state. Use GET /accounts/{accountId}/balances to retrieve the latest balances for any account, whether fiat or crypto. Balances are read-only. They are updated automatically as transactions (payments, conversions, transfers, fees) affect the account.

Balance Types

Each balance entry has a type that indicates what portion of the funds it represents:
TypeDescription
availableFunds that are immediately spendable. This is the amount you can use for payments, conversions, and transfers right now.
pendingFunds that are in transit. These are expected to settle and become available, but are not yet confirmed (e.g., pending ACH credits).
heldFunds that are reserved for a specific purpose. These are part of the total balance but are not available for spending (e.g., funds locked for a pending payment or compliance hold).
totalThe sum of all funds in the account, regardless of availability. Equal to available + pending + held.
The available balance is the most important number for determining whether an account has sufficient funds to initiate a payment or conversion. Always check available rather than total before creating transactions.

Querying Balances

curl -X GET https://sandbox.api.openfx.com/v1/accounts/acc_01953e1a5f4b7002/balances \
  -H "Authorization: Bearer $API_KEY" \
  -H "X-Signature: $SIGNATURE" \
  -H "X-Timestamp: $TIMESTAMP"

Fiat Balance Response

For a fiat account (demand_deposit or virtual), balances include currency and amount:
{
  "items": [
    {
      "type": "available",
      "currency": "USD",
      "value": "1000000",
      "lastUpdatedAt": "2026-02-23T14:30:00Z"
    },
    {
      "type": "pending",
      "currency": "USD",
      "value": "250000",
      "lastUpdatedAt": "2026-02-23T14:30:00Z"
    },
    {
      "type": "held",
      "currency": "USD",
      "value": "50000",
      "lastUpdatedAt": "2026-02-23T14:30:00Z"
    },
    {
      "type": "total",
      "currency": "USD",
      "value": "1300000",
      "lastUpdatedAt": "2026-02-23T14:30:00Z"
    }
  ]
}

Crypto Balance Response

For a crypto account (wallet), balances include asset in addition to currency and amount:
{
  "items": [
    {
      "type": "available",
      "currency": "USDC",
      "asset": "USDC",
      "value": "5000000",
      "lastUpdatedAt": "2026-02-23T14:30:00Z"
    },
    {
      "type": "pending",
      "currency": "USDC",
      "asset": "USDC",
      "value": "120050",
      "lastUpdatedAt": "2026-02-23T14:30:00Z"
    },
    {
      "type": "held",
      "currency": "USDC",
      "asset": "USDC",
      "value": "0",
      "lastUpdatedAt": "2026-02-23T14:30:00Z"
    },
    {
      "type": "total",
      "currency": "USDC",
      "asset": "USDC",
      "value": "5120050",
      "lastUpdatedAt": "2026-02-23T14:30:00Z"
    }
  ]
}

Amounts Are Always Strings

All monetary amounts in the OpenFX API are represented as strings, never floating-point numbers. This prevents rounding errors inherent in IEEE 754 floating-point arithmetic, which is critical for financial calculations.Always parse amounts using a decimal/big-number library in your code, not native floating-point types.
Examples of correct handling:
from decimal import Decimal

# Correct: use Decimal for financial math
available = Decimal(balance["amount"])  # Decimal("10000.00")
fee = Decimal("25.50")
remaining = available - fee  # Decimal("9974.50")

# Incorrect: never use float
# available = float(balance["amount"])  # 10000.0 — precision loss risk

Multi-Currency Balances

A fiat account holds balances in its designated currency. If you need to hold multiple currencies, create separate accounts for each currency and query their balances independently.
# Query balances across multiple accounts
accounts = ["acc_usd_001", "acc_gbp_001", "acc_eur_001"]
for account_id in accounts:
    response = requests.get(
        f"https://sandbox.api.openfx.com/v1/accounts/{account_id}/balances",
        headers=headers,
    )
    balances = response.json()["items"]
    available = next(b for b in balances if b["type"] == "available")
    print(f"{account_id}: {available['amount']} {available['currency']}")

Balance History and Transaction Ledger

The balances endpoint returns a point-in-time snapshot. For a detailed history of all balance-affecting events, use the transaction ledger at GET /transactions. Filter by accountId to see every debit and credit that has occurred on an account.Transactions include direction (debit/credit), type (payment_out, payment_in, conversion_debit, etc.), and linkedTransactionId to pair the debit and credit legs of the same operation.
curl -X GET "https://sandbox.api.openfx.com/v1/transactions?accountId=acc_01953e1a5f4b7002" \
  -H "Authorization: Bearer $API_KEY" \
  -H "X-Signature: $SIGNATURE" \
  -H "X-Timestamp: $TIMESTAMP"

API Reference