Unified Account Model

OpenFX uses a single /accounts resource for both fiat currency accounts and crypto asset accounts. There are no separate wallet endpoints. Whether you are holding USD, EUR, or USDC, the same API surface manages account creation, balance queries, and lifecycle transitions.

Why operational accounts matter

Operational accounts are the foundation of the OpenFX business model. They solve a critical problem: capital leakage from off-platform fund flows. Today, customers sweep funds to external bank accounts between FX trades and payouts. Every dollar that leaves OpenFX between trades is a dollar that must be won back. Operational accounts on the platform change the economics:
  • Funds stay on-platform — working capital remains accessible for trades, payouts, and conversions without external bank transfers
  • Customer switching costs rise — once balances are held on-platform, customers are less likely to move to a competitor
  • Retained balances deepen on-platform liquidity — making FX execution instant, capital-efficient, always-on (24/7/365), and cheaper to operate
This is the engine of the liquidity flywheel: retained balances produce tighter spreads, which attract more volume, which deepens liquidity further. Customers who hold balances, receive inbound payments, and originate outbound payments generate 3-5x the revenue per customer compared to FX-only relationships.
The unified account model — a single /accounts resource for both fiat and crypto — is a locked architectural decision. There are no separate /wallets endpoints. This unification simplifies the API surface and avoids artificial splits between asset types.
The account type field determines the flavor:
TypeDescriptionKey FieldsUse Case
demand_depositStandard fiat bank accountcurrency (ISO 4217)Hold and move fiat currencies (USD, GBP, EUR)
walletCrypto asset accountasset, chainHold and move stablecoins (USDC, USDT, EURC, PYUSD)
virtualSegregated fiat sub-accountcurrency (ISO 4217)Client money segregation, escrow, earmarking
All account IDs use the acc_ prefix followed by a UUIDv7 identifier (e.g., acc_01953e1a5f4b7002). This prefix makes account references instantly recognizable in logs and debugging.

Account Lifecycle

Every account progresses through a defined set of statuses:
StatusDescription
pendingAccount has been created but is not yet ready for use.
activeAccount is fully operational. Balances can be credited and debited.
suspendedAccount is temporarily frozen. No transactions allowed until reactivated.
closedAccount is permanently closed. This is a terminal state.
An account can only be closed when it has a zero balance and no pending transactions. Attempting to close an account with remaining funds returns a 422 error.

Account Purpose

The purpose field classifies how the account will be used. This aids compliance reporting and internal categorization.
PurposeDescription
operatingGeneral operating funds
payrollPayroll disbursement
vendor_paymentsPayments to vendors and suppliers
treasuryTreasury and cash management
collectionsReceiving inbound collections
disbursementOutbound disbursements
escrowEscrow or trust funds
otherAny other purpose
The purpose field is optional at creation time and can be set based on your business needs.

Resource Hierarchy

Accounts sit at the center of the banking layer. Here is how they relate to other resources:
Customer (cus_)
  └── Account (acc_)
        ├── Balances (multi-currency)
        ├── Account Numbers (an_)  <- fiat deposit rails
        ├── Blockchain Addresses (ba_)  <- crypto deposit addresses
        └── Transactions (txn_)  <- ledger entries
  • A customer owns one or more accounts.
  • Each account has balances across one or more currencies or assets.
  • Fiat accounts receive deposits through account numbers (ACH routing, wire, IBAN, etc.).
  • Crypto accounts receive deposits through blockchain addresses (Ethereum, Solana, etc.).
  • All balance-affecting events are recorded as transactions in the ledger.

Creating Accounts

curl -X POST https://sandbox.api.openfx.com/v1/accounts \
  -H "Authorization: Bearer $API_KEY" \
  -H "X-Signature: $SIGNATURE" \
  -H "X-Timestamp: $TIMESTAMP" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
    "customerId": "cus_01953e1a5f4b7000",
    "type": "demand_deposit",
    "currency": "USD",
    "label": "USD Operating Account",
    "purpose": "operating"
  }'
curl -X POST https://sandbox.api.openfx.com/v1/accounts \
  -H "Authorization: Bearer $API_KEY" \
  -H "X-Signature: $SIGNATURE" \
  -H "X-Timestamp: $TIMESTAMP" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
    "customerId": "cus_01953e1a5f4b7000",
    "type": "wallet",
    "asset": "USDC",
    "chain": "ethereum",
    "label": "USDC Ethereum Account"
  }'
Prerequisites: The customer must be in active status (KYB approved) and have the accounts capability before you can create accounts.

Next Steps After Account Creation

Once you have created an account, set up the deposit infrastructure so the account can receive funds:
  • Fiat accounts: Create account numbers to receive bank deposits. See Account Numbers.
  • Crypto accounts: Create blockchain addresses to receive on-chain deposits. See Blockchain Addresses.

API Reference