Balances

Details about where a customer's money sits.

Balances live on the customer. The virtual account that received the money does not hold one, and neither does the deposit address.

GET /v1/customers/{customerId}/balances

A balance grows when a deposit is credited. In sandbox nothing is provisioned for you and you cannot transfer funds in, so the way to put money on a customer is to simulate a deposit. See Testing in sandbox.

Four classes, plus a total

ClassMeans
availableSpendable funds. This is the only class you can act on.
pendingFunds have arrived but have not settled yet.
heldSettled but locked, usually against something in flight.
blockedA control has restricted these funds.
totalThe sum of the classes above. Use it for display. It won't tell you whether a payment will go through.

Internal ledger classes never appear here. These values are what the customer actually holds.

Check available before every execution. A payout or conversion against any other class fails with insufficient_balance. That is a 422, and retrying it will not make it succeed.

What a balance can be

Each entry carries a scope.type:

  • stablecoin_balance is held in USDC or USDT and carries a chain.
  • corporate_account is a USD balance the customer holds with Alfred.
  • local_stablecoin covers MXNa, ARSa, COPa and BRZ.

A customer can hold several at once. Filter with ?type= when you only care about one kind.

The availability rule

Money being received and money being spendable are two different moments. The gap between them is easy to miss.

A deposit reaching PROCESSING with FUNDS_HELD means the conversion confirmed and the controls cleared. The funds still aren't spendable at that point. settlement_status reaches SETTLED and the balance becomes available only once delivery to the vault is confirmed as well.

Don't release anything on an intermediate status. Wait for deposit.credited and then read available.

The Corporate USD Account

POST /v1/customers/{customerId}/corporate_account
GET  /v1/customers/{customerId}/corporate_account

This is an opt-in USD balance the customer holds with Alfred. It's somewhere to keep money, and nobody pays into it directly.

It isn't available to a SUB_CUSTOMER. The request is refused with customer_type_ineligible before anything is locked. Expect the balance to sit at pending until the provider's per-holder approval comes back, which is outside our control.

Reconciling

Three reads cover reconciliation, and each one answers a different question.

The journal records every movement.

GET /v1/customers/{customerId}/balance_transactions

Every flow posts into it. Each entry carries source back to the deposit, conversion or payout that created it, which is what makes client-side reconciliation possible.

Statements cover a date range.

GET /v1/customers/{customerId}/statements?fromDate=&toDate=

They give opening and closing balances plus every item that reached a terminal status inside the window.

Statements are never backdated. An item that finalizes after the window appears on the day it finalized rather than the day it started. Pending items are excluded by design, so a statement will not tie to a live balance read. That is intended behavior, and it's worth knowing before someone spends an afternoon on the difference.

Assets under management cover the whole book.

GET /v1/aum?scope=&type=

This returns totals across everything under your key. There's no customer parameter and no partner parameter, because your key defines the book. scope takes sub_customers, self or all.

You can rely on per-customer balance reads at the same asOf summing exactly to this figure.


Did this page help you?