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

Fetch a wallet

The response includes the wallet balance and its positions:
Key fields in the response: The positions array includes cash positions and yield sources in your strategy allocation.
  • yield_source — a held or configured yield position. id is its public yield-source ID. allocationGroup, token, and chain identify its funding group; pct, when present, is its target weight within that group. A resolved source also includes mode, apyBps, navUpdateMode, and priceAsOf.
  • cash — idle USDC or USDT sitting in the wallet’s deposit addresses. Cash positions include token and chain; configured cash targets may include pct. Cash position IDs follow cash:<chain>:<token>, using the network key for the wallet’s environment.
Configured zero-value cash and yield targets can appear for every strategy group, including Ethereum USDT and TRON USDT, so clients can render the current strategy. The sum of all positions[].valueUsd equals balance.totalUsd. Use strategyAllocations for desired targets and positions[].allocationGroup to group actual holdings. usdt is Ethereum USDT, while usdt:tron is native TRON USDT. Each group is weighted independently; the wallet’s balance totals span all groups. A manually allocated wallet still identifies each holding’s group even though its strategyAllocations is null. Balances are calculated from refreshed onchain holdings and price feeds, then cached for faster reads. They may briefly lag deposits or withdrawals.

When idle stablecoins move into yield

Idle cash is swept into yield positions through rebalances. Each allocation group is evaluated independently, using its compatible funds and strategy. Rebalances only run when the available idle balance can produce executable yield-entry legs. If the cash cannot meet the minimum for each planned movement, it stays in cash and remains withdrawable; no error is returned. Splitting a deposit across several targets can leave each movement below the minimum. See rebalance examples for how the thresholds apply.

Balance definitions

  • totalUsd answers: “How much value does the customer own?”
  • withdrawableUsd answers: “How much gross wallet value can the customer withdraw now before plan-specific fees?”
  • reservedUsd answers: “How much customer-owned value is currently reserved by active wallet work?”
  • earnedUsd answers: “How much lifetime yield has this wallet earned?”
Funds awaiting settlement, such as an in-progress withdrawal or rebalance, remain included in totalUsd but may be unavailable for withdrawal. Use withdrawableUsd to show the amount currently available before withdrawal fees. A pending claim whose workflow has been cancelled is unavailable for withdrawal until settlement is reconciled; it does not prevent withdrawing other available cash or positions.

reservedUsd timing

reservedUsd reflects the amount reserved by active withdrawal and rebalance work. Broadcasting a transaction does not immediately release reserved funds. Ground keeps them reserved until it confirms the resulting balance. A completed operation can therefore remain reserved briefly while the balance updates:
  • 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.

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).

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).

Earned and APY over time

GET /v2/accounting/yield/earned-series returns a time series for charting wallet performance, scoped to one wallet (walletId) or the whole organization (scope=organization). Each point carries two distinct metrics:
  • cumulativeEarnedUsd — lifetime cumulative earned value, mark-to-market. This includes realized and unrealized gains: it moves both ways and can dip to show losses, unlike the monotonic balance.earnedUsd.
  • blendedApyBps — the wallet’s blended APY at that point, in basis points. Each held yield source contributes its trailing ~30-day NAV growth (annualized), weighted by marked position value, with idle cash weighted at 0%. It describes the rate the allocation is positioned at, independent of wallet size — not what was earned, which the cumulative fields carry.
Wallet APY is unavailable while the wallet holds non-USD investments. Earnings remain available, and each investment’s APY is shown in its own currency.

List wallets

Supports cursor-based pagination. The response includes a nextCursor field for fetching subsequent pages. See 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:
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 for registration and payload details.

Stock holdings

positions remains a flat list of actual holdings. A stock position uses kind: "stock" and includes assetSymbol, exact integer nativeUnits, and indicative price fields. Interpret nativeUnits using tokenDecimals (also returned by the catalog). Stocks are held in manual wallets and have no automatic strategy target. Stock appreciation, depreciation and realized trading gains affect wallet value but are excluded from earnedUsd and yield reporting. A last observed stock mark may be stale: inspect priceFreshness and priceAsOf before presenting it as current. A missing mark is unavailable rather than a zero price.

Preview a stock allocation

For a manual wallet, use the position ID from the catalog as the destination:
An illustrative preview includes the requested dollar allocation and a separate stock quote:
afterUsd describes the requested allocation. The quote estimates actual token quantities and cash spend; it does not guarantee the eventual value or execution price. Cash quantities use the cash token’s decimals (six for Ethereum USDC). Stock quantities use stockTokenDecimals. Submit the same allocations to POST /v2/wallets/{id}/allocate with a new requestId to create the instruction. Ground requests a fresh quote before execution and keeps the buy within its available cash budget. Read wallet activity until the instruction completes, then read the wallet’s settled positions. Unspent cash remains in the wallet. For paths with earlier redemption or bridge operations, their fees can reduce the cash available for the stock purchase. A sell quote includes minimumCashNativeUnits in addition to the estimated receive amount. Stock previews return HTTP 503 when a current quote within the permitted price bounds is unavailable; retry later. A pair with no supported conversion path returns HTTP 400.