Prerequisites
Set your base URL and API token once, then reuse them for every request. Use sandbox while you build, then switch to production by swapping the base URL. The endpoint structure stays the same, but sandbox uses explicit testnet chain keys such asethereum_sepolia.
cURL
Conventions
- JSON field names are
camelCase. - Enum-like string values (for example
status,type, and webhookevent/eventTypes) arelower_snake_case.- Example:
payoutLeg.status = pending_customer_approval
- Example:
1. List available yield sources
Fetch the yield sources you can allocate to. Each yield source has a stableid you will use as yieldSourceId when creating a wallet.
cURL
data array. Note each source’s id and apyBps to decide your allocation.
2. Create a portfolio wallet
Create a Portfolio Wallet by passingstrategy.allocations with your chosen yield allocation. Allocation percentages must sum to 100.
cURL
yieldSourceId and pct.
Wallet creation is asynchronous. The POST response returns immediately with status: "creating" and the wallet id, but depositAddresses are not yet available — they are populated once provisioning completes. Save the wallet id for the remaining steps:
cURL
3. Wait for the wallet to activate
PollGET /v2/wallets/{id} every 1-2 seconds until status === "idle". Only then are depositAddresses populated. If status === "failed", inspect failureReason and retry creation with a new requestId.
See Polling → Poll until wallet is active for a ready-to-paste snippet in cURL, Node, and Python.
4. Deposit actual funds
Once the wallet isactive, grab the chain-specific deposit address from the poll response and send a stablecoin transfer from your custody to that address.
Plain
5. Await Deposit Confirmation
Deposits are detected on-chain and then processed. You can track the latest deposit status either by polling the deposits endpoints or by subscribing to webhooks. Poll (REST):- List deposits for a wallet:
GET /v2/wallets/{id}/deposits - Fetch a single deposit:
GET /v2/wallets/{id}/deposits/{depositId}
cURL
portfolio_wallet.deposit.status_changed
deposit.status):
processingcompletedfailed
6. Fetch the updated balance
Fetch the wallet to see current balances after the deposit is processed. Key fields in the response:balance.totalUsd— total wallet value across positions, cash, and accrued yieldbalance.withdrawableUsd— conservative amount the customer can withdraw nowbalance.reservedUsd— customer-owned value currently reserved by active withdrawals or rebalancesbalance.earnedUsd— lifetime yield earned since wallet creationpositions[]— current cash, bridge, and yield-source balances. Yield-source positions include target allocations.
cURL
7. Withdraw (including the signing flow)
Ground uses Turnkey to manage signing flows, but you do not need a relationship with Turnkey to sign approvals.
pending_customer_approval; complete the approval in Ground Portal or through the Ground Turnkey approval endpoints.
cURL
id from the response (this is the withdrawal id used for status checks):
cURL
GET /v2/turnkey/activities/pending, request POST /v2/turnkey/activity-approval-request, stamp the returned payload locally, then submit POST /v2/turnkey/activities/{activityId}/vote. See Transaction Approvals for verification checks and approval patterns.
8. Await Withdrawal Confirmation
After approval (if required), the withdrawal is kicked off automatically. You can track the latest withdrawal status either by polling the withdrawal endpoint or by subscribing to webhooks. Poll (REST):cURL
portfolio_wallet.rebalance.status_changed(cash deployment and strategy adjustment progress)portfolio_wallet.withdrawal.status_changedportfolio_wallet.withdrawal.payout.status_changed(per-leg payouts)
withdrawal.status):
processingpartially_completedcompletedfailedcancelled
withdrawal.payoutLegs[].status) and payout step states (withdrawal.payoutLegs[].steps[].state):
processingcreatedpending_customer_approvalcompletedfailedcancelled
name, chain, state, txKind, stepKind, protocolType, and sequenceRole. txHash is included when a broadcast transaction hash is available.
For more detail, see Transaction Approvals and the API Reference withdrawal endpoints.