# Balances and holds

Read Funding and Trading balances, understand available versus reserved amounts, follow equity, and reconcile ledger transfer history with LedgerReadService.

Every Main Account and every Subaccount has two balance areas for each Asset:

- **Funding** is the on-chain Funding Account on Polyester Chain. It receives deposits and sends Funding transfers and withdrawals.
- **Trading** is the Unified Trading Account: the off-chain balance used by orders, triggers, fills, fees, Trading withdrawals, and internal transfers.

Moving value between them is a transfer. See [Internal transfers](https://testnet.polyester.com/docs/developer-docs/funds-transfers/internal-transfers).

## Read balances

[`LedgerReadService.GetBalances`](https://testnet.polyester.com/docs/api-docs/connect/ledger.read.v1.LedgerReadService/GetBalances) ([`GET /v1/balances`](https://testnet.polyester.com/docs/api-docs/rest/GET/v1/balances)) returns one row for every supported Asset, including zero balances. Pass `subaccountId` to read a Subaccount. Session callers need a role on that Subaccount. API keys need `READ_BALANCES` and follow their scope. Without `subaccountId`, a Subaccount-scoped API key reads its bound Subaccount, and every other caller reads its Main Account.

Each row carries the Asset's total Trading balance (`trading`), the part of it committed to open orders, triggers, or pending movements (`reserved`), what a new order, transfer, or withdrawal can use now (`available`), and the Funding balance (`funding`). `tradingRevision` versions `trading`, `reserved`, and `available` together; `fundingRevision` versions `funding`. Field schemas are in the API reference.

ConnectRPC carries amounts as U128 at a fixed 18-decimal scale and identifies the Asset by `assetId`. That scale does not depend on the Asset's `quantity_scale`, which applies to order quantities and the fields that name it, not to balances. REST renders decimal strings and the Asset `symbol`. See [Scaled integers](https://testnet.polyester.com/docs/developer-docs/connectrpc/scaled-integers).

Use `available` as returned. Do not derive it from `trading` minus `reserved`. When you merge a REST snapshot with realtime updates, keep the copy with the higher revision. Revision `0` means no state has been observed yet.

## Available and reserved

When an action commits funds, Polyester reserves them in Trading. The reserve leaves `available` immediately, so the same funds cannot back two actions. Any unused part returns to `available` when the action fills, is canceled, completes, or fails.

| Source of a reserve                 | What is reserved                                                                                                                                                                                                   |
| ----------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Open sell order                     | The remaining base quantity.                                                                                                                                                                                       |
| Open buy order                      | The remaining quote cost, plus a fee allowance when the fee is paid in quote.                                                                                                                                      |
| Standalone stop-loss or take-profit | Funds for the child order, reserved at creation. See [Stop-loss and take-profit](https://testnet.polyester.com/docs/developer-docs/shared-concepts/triggers/stop-loss-and-take-profit#funds-reserved-at-creation). |
| Trading withdrawal                  | The gross withdrawal amount until the withdrawal settles, fails, or is refunded.                                                                                                                                   |
| Internal transfer                   | The transfer amount while the transfer completes.                                                                                                                                                                  |

A request that `available` cannot cover is rejected with `INSUFFICIENT_FUNDS`. [Preview order](https://testnet.polyester.com/docs/developer-docs/shared-concepts/preview-order) checks admissibility without reserving anything.

Polyester does not publish a per-hold read: individual holds, their identifiers, and their expiry times are not part of the public API. Use each Asset's `reserved` from `GetBalances` for the total held, and your order, trigger, and movement records for the cause.

## Equity

Equity values balances in USDT using market prices.

| Method                                                                                                                                                    | Use                                                                     |
| --------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------- |
| [`GetEquityHistorySeries`](https://testnet.polyester.com/docs/api-docs/connect/ledger.read.v1.LedgerReadService/GetEquityHistorySeries)                   | One account's equity over a range, grouped by balance area or by Asset. |
| [`GetPortfolioEquitySnapshot`](https://testnet.polyester.com/docs/api-docs/connect/ledger.read.v1.LedgerReadService/GetPortfolioEquitySnapshot)           | Current equity across the Main Account and every owned Subaccount.      |
| [`GetPortfolioEquityHistorySeries`](https://testnet.polyester.com/docs/api-docs/connect/ledger.read.v1.LedgerReadService/GetPortfolioEquityHistorySeries) | Portfolio equity history across owned accounts.                         |
| [`GetBalanceHistory`](https://testnet.polyester.com/docs/api-docs/connect/ledger.read.v1.LedgerReadService/GetBalanceHistory)                             | Balance series per Asset and balance area.                              |

REST routes: [`GET /v1/equity/history/series`](https://testnet.polyester.com/docs/api-docs/rest/GET/v1/equity/history/series), [`GET /v1/equity/portfolio/snapshot`](https://testnet.polyester.com/docs/api-docs/rest/GET/v1/equity/portfolio/snapshot), [`GET /v1/equity/portfolio/history/series`](https://testnet.polyester.com/docs/api-docs/rest/GET/v1/equity/portfolio/history/series), and [`GET /v1/balances/history`](https://testnet.polyester.com/docs/api-docs/rest/GET/v1/balances/history).

Ranges run from one day to 365 days. Equity values are USDT scaled by 1e4; balance-history points are scaled by 1e7. The two portfolio methods need an interactive Main Account session; API keys are refused with `AUTH_SESSION_KIND_NOT_ALLOWED`.

## Ledger history

[`ListTransfers`](https://testnet.polyester.com/docs/api-docs/connect/ledger.read.v1.LedgerReadService/ListTransfers) ([`GET /v1/transfers`](https://testnet.polyester.com/docs/api-docs/rest/GET/v1/transfers)) lists finalized ledger transfers for one account: deposits, withdrawals, trade legs, fees, rebates, internal transfers, and moves between Funding and Trading. Each transfer has a debit and a credit leg that share `transferId`.

- `transferCode` gives the reason, such as `DEPOSIT`, `TRADE_BASE`, `TAKER_FEE`, `INTERNAL_TRANSFER`, or `TRADING_TO_FUNDING`.
- `account` (ConnectRPC `accountCode`) is the balance area the row affects, and `balanceAfter` is that area's balance after the transfer. `isDebit` tells the debit leg from the credit leg.
- `source` and `destination` are display sides. Private counterparties and system accounts are never identified.
- `flowId` links deposits and withdrawals to their lifecycle flow.

Filter by Asset (`ledger`) and by an inclusive time range in microseconds (`timestampMin` and `timestampMax`; ConnectRPC `tsMinUs` and `tsMaxUs`). ConnectRPC also filters by `transferCode`. Rows are oldest first unless you set `reversed` to `true`. Page with `pageToken`; `limit` defaults to 100 and allows up to 1000. API keys need `READ_INTERNAL_TRANSFERS` (or `INTERNAL_TRANSFER`) to call it.

> **Reconcile on the transfer identity**
>
> Treat `transferId`, the balance area, and `isDebit` together as the identity of one leg. A realtime update with the same identity replaces the earlier copy, for example when a deposit leg gains its `flowId`.

Realtime [balance](https://testnet.polyester.com/docs/api-docs/streams/private-ledger-balances) and [transfer](https://testnet.polyester.com/docs/api-docs/streams/private-ledger-transfers) updates are available over [WebSocket JSON](https://testnet.polyester.com/docs/developer-docs/rest/websocket-json) and [WebSocket Protobuf](https://testnet.polyester.com/docs/developer-docs/connectrpc/websocket-protobuf). Field schemas are in the [API reference](https://testnet.polyester.com/docs/api-docs), and error codes under [Balances and transfer history](https://testnet.polyester.com/docs/developer-docs/error-handling/error-codes#balances-and-transfer-history).
