> ## Documentation Index
> Fetch the complete documentation index at: https://docs.groundtech.co/llms.txt
> Use this file to discover all available pages before exploring further.

# Balances and Yield

> Monitor wallet balances, positions, and yield metrics.

Once your wallet is funded, use these endpoints to track balances, positions, and yield.

## Fetch a wallet

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl -X GET "$BASE_URL/v2/wallets/$WALLET_ID" \
  -H "Authorization: Bearer $API_TOKEN"
```

The response is a clean neobank-style shape:

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "id": "9d1a1c83-3a1c-4c14-9c5a-0c9a57a4a7db",
  "label": "Core Yield Portfolio",
  "status": "idle",
  "balance": {
    "totalUsd": "100250.000000",
    "earnedUsd": "250.000000",
    "reservedUsd": "0.000000",
    "withdrawableUsd": "100250.000000"
  },
  "createdAt": "2026-02-05T08:15:00.000Z",
  "positions": [
    { "id": "cash:ethereum_sepolia:usdc", "kind": "cash", "label": "Cash (Ethereum Sepolia)", "valueUsd": "0.000000" },
    { "id": "syrup-usdc", "pct": 40, "kind": "yield_source", "label": "Syrup USDC", "valueUsd": "40100.000000", "yieldSourceId": "syrup-usdc", "mode": "active", "apyBps": 491 },
    { "id": "morpho-gauntlet-usdc", "pct": 30, "kind": "yield_source", "label": "Morpho Gauntlet USDC Prime", "valueUsd": "30075.000000", "yieldSourceId": "morpho-gauntlet-usdc", "mode": "active", "apyBps": 500 },
    { "id": "morpho-steakhouse-usdc", "pct": 30, "kind": "yield_source", "label": "Morpho Steakhouse USDC Prime", "valueUsd": "30075.000000", "yieldSourceId": "morpho-steakhouse-usdc", "mode": "active", "apyBps": 500 }
  ],
  "strategyAllocations": {
    "usdc": [
      { "yieldSourceId": "syrup-usdc", "targetWeightBps": 4000 },
      { "yieldSourceId": "morpho-gauntlet-usdc", "targetWeightBps": 3000 },
      { "yieldSourceId": "morpho-steakhouse-usdc", "targetWeightBps": 3000 }
    ],
    "usdt": [
      { "yieldSourceId": "cash", "targetWeightBps": 10000, "token": "usdt", "chain": "ethereum_sepolia" }
    ]
  },
  "failureReason": null,
  "depositAddresses": {
    "solana_devnet": "DmaePN7kL6WjSecMaH4urdS8zN8FwNPTxbdTqFwAw6Fd",
    "ethereum_sepolia": "0xFf71D07826d0aFcEcDF07Be9c499f9DDF3ee5cFa"
  }
}
```

Key fields in the response:

| Field                     | Description                                                                                                 |
| ------------------------- | ----------------------------------------------------------------------------------------------------------- |
| `status`                  | `idle`, `withdrawal_active`, `rebalance_active`, `withdrawal_and_rebalance_active`, `creating`, or `failed` |
| `balance.totalUsd`        | Gross customer-owned wallet value, including economically-owned funds that are still in transit             |
| `balance.withdrawableUsd` | Conservative amount that can be withdrawn now                                                               |
| `balance.reservedUsd`     | Customer-owned value currently reserved by active withdrawal or rebalance work                              |
| `balance.earnedUsd`       | Lifetime yield earned                                                                                       |
| `positions[]`             | Per-position balances with USD values and target allocations                                                |
| `strategyAllocations`     | Desired targets grouped by stablecoin, expressed in basis points                                            |

The `positions` array includes cash positions and yield sources in your strategy allocation.

* **`yield_source`** — a strategy position. These entries include `yieldSourceId` and `pct`.
* **`cash`** — idle USDC or USDT sitting in the wallet's deposit addresses. Cash positions include `token` and `chain`; configured cash targets may include `pct`.

Configured zero-value cash and yield targets can appear so clients can render the current strategy. The sum of all `positions[].valueUsd` equals `balance.totalUsd`.

Balances are computed from refreshed onchain holdings + price feeds and cached for fast reads. They may briefly lag deposits or withdrawals.

### When idle stablecoins move into yield

Idle cash is swept into yield positions through rebalances. USDC follows the USDC strategy and USDT follows the USDT strategy; Ground does not convert between them. Rebalances only run when the available idle balance can produce executable yield-entry legs.

<Note>
  Rebalance minimums are environment-configured and applied per executable leg. Sandbox uses small minimums (e.g. 5 stablecoin units per leg) so you can test with small amounts; production minimums are typically higher. If idle cash cannot produce executable legs above the configured threshold, those funds remain idle and withdrawable instead of being swept into yield -- no error is returned.
</Note>

If idle cash is split across multiple strategy targets, each resulting target leg must meet the active environment's configured minimum. For example, if the active minimum is 5 units per leg, an 8 USDT idle balance with a 50/50 USDT strategy would split into two 4 USDT target legs, so no rebalance legs are created.

### Balance definitions

* `totalUsd` answers: "How much value does the customer own?"
* `withdrawableUsd` answers: "How much can the customer withdraw now?"
* `reservedUsd` answers: "How much customer-owned value is currently reserved by active wallet work?"
* `earnedUsd` answers: "How much lifetime yield has this wallet earned?"

`totalUsd`, `withdrawableUsd`, and `reservedUsd` are intentionally not interchangeable. Value can remain customer-owned while still being unavailable to withdraw immediately, for example when a withdrawal or rebalance is settling.

Internally, Ground keeps that value represented through explicit transfer boundaries. When funds move from one representation to another, the transfer row stays active until the destination representation is durably written or observed. That is what keeps `totalUsd` from dipping during internal protocol steps.

### `reservedUsd` timing

`reservedUsd` reflects the amount reserved by active withdrawal and rebalance work. It is set when the system reserves liquidity for a wallet workflow.

The reservation is not always cleared immediately when a transaction broadcasts. It stays active until Ground's ledger and holdings refresh confirm the next representation of the funds. In practice:

* **Workflow initiated**: `reservedUsd` increases, `withdrawableUsd` decreases by the same amount, `totalUsd` stays the same.
* **Workflow completed**: `reservedUsd` may remain briefly while the next ledger or holdings refresh catches up.
* **Refresh catches up**: `reservedUsd` decreases back toward zero, and `totalUsd` reflects the settled holdings.
* **Workflow cancelled**: `reservedUsd` decreases, `withdrawableUsd` increases back to its pre-workflow level.

The invariant `0 <= withdrawableUsd <= totalUsd` always holds.
The invariant "customer-owned value is always represented somewhere" also always holds.

### Customer-facing valuation notes

* `syrup-usdc` is valued from live onchain share-to-assets conversion and can move continuously.
* Morpho ERC-4626 vaults exposed by the live catalog are valued from live onchain ERC-4626 conversion reads.
* Treat NAV-based positions as protocol valuations, not guaranteed 1:1 stablecoin marks at every instant.

For destination-specific initiation readiness and a sourcing plan, use `POST /v2/wallets/:id/withdrawal-preview` (see [Withdraw Funds](/docs/portfolio-wallets/withdraw-funds)).

## Yield metrics

You can monitor yield through the wallet response:

* `balance.earnedUsd` -- lifetime yield earned since wallet creation
* `balance.totalUsd` -- total value including accumulated yield

For a detailed breakdown including per-source APY, use `GET /v2/wallets/:id/yield` (see [Calculating Yield Accrual](/docs/portfolio-wallets/calculating-yield-accrual)).

## List wallets

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl -X GET "$BASE_URL/v2/wallets?limit=25" \
  -H "Authorization: Bearer $API_TOKEN"
```

Supports cursor-based pagination. The response includes a `nextCursor` field for fetching subsequent pages. See [API Conventions](/docs/portfolio-wallets/api-conventions) for details.

## Look up a wallet

Look up a wallet by `requestId`, `id`, `label`, `search`, `status`, or `createdAtGte` using the list endpoint's filters. Filters can be combined when you want to narrow the result set:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl -X GET "$BASE_URL/v2/wallets?requestId=$REQUEST_ID" \
  -H "Authorization: Bearer $API_TOKEN"
```

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl -X GET "$BASE_URL/v2/wallets?label=My%20Portfolio" \
  -H "Authorization: Bearer $API_TOKEN"
```

The response is the standard cursor-paginated list shape (`{ "data": [...], "nextCursor": ... }`); a matching wallet appears in `data`.

## Balance and workflow webhooks

Subscribe to workflow lifecycle events and fetch the wallet when you need a fresh balance snapshot:

* `portfolio_wallet.deposit.status_changed` -- fires when an external deposit posts to the wallet
* `portfolio_wallet.rebalance.status_changed` -- fires as Ground deploys cash or adjusts strategy positions
* `portfolio_wallet.withdrawal.status_changed` -- fires when withdrawals change the wallet's available balance

See [Webhooks](/docs/portfolio-wallets/webhooks) for registration and payload details.
