Skip to main content
This quickstart walks through the full Portfolio Wallet lifecycle: reviewing yield sources, creating a wallet, funding it, and initiating a withdrawal.

Prerequisites

Create your API key at portal.groundtech.co, then export it below.
export BASE_URL="https://sandbox.groundtech.co"
export GROUND_API_TOKEN="your_api_token"
See API Conventions for authentication, pagination, rate limits, and error handling.

1. Review the yield source catalog

Fetch the current yield source catalog, then decide the allocation you want to use for wallet creation.
curl -X GET "$BASE_URL/v2/wallets/yield-sources" \
  -H "Authorization: Bearer $GROUND_API_TOKEN"

2. Create a Portfolio Wallet

Choose the allocation strategy you’d like for your wallet:
curl -X POST "$BASE_URL/v2/wallets" \
  -H "Authorization: Bearer $GROUND_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "requestId": "0b7e3b4d-88a5-4a75-8c0f-3b7b4f9d9f1d",
    "label": "Core Yield Portfolio",
    "strategy": {
      "allocations": [
        { "yieldSourceId": "syrup-usdc", "pct": 40 },
        { "yieldSourceId": "morpho-gauntlet-usdc", "pct": 30 },
        { "yieldSourceId": "morpho-steakhouse-usdc", "pct": 30 }
      ]
    }
  }'
The response includes depositAddresses — one per supported chain.

3. Deposit USDC

Send USDC to the wallet’s deposit address on any supported chain. In sandbox, use Sepolia USDC on Ethereum. You can get Sepolia USDC from the Circle faucet or bridge testnet ETH via the Sepolia faucet.

4. Check balance and yield

curl "$BASE_URL/v2/wallets/$WALLET_ID" \
  -H "Authorization: Bearer $GROUND_API_TOKEN"
{
  "id": "9d1a1c83-3a1c-4c14-9c5a-0c9a57a4a7db",
  "label": "Core Yield Portfolio",
  "createdAt": "2026-02-05T08:15:00.000Z",
  "depositAddresses": {
    "arbitrum": "0x21246509968c4d24611f414560971AEc2e3A079B",
    "ethereum": "0x21246509968c4d24611f414560971AEc2e3A079B"
  },
  "balance": {
    "totalUsd": "100000.000000",
    "withdrawableUsd": "100000.000000",
    "availableToInitiateUsd": "100000.000000",
    "pendingWithdrawalUsd": "0.000000",
    "inTransitUsd": "0.000000",
    "earnedUsd": "1250.000000"
  },
  "positions": [
    { "yieldSourceId": "syrup-usdc", "name": "Syrup USDC", "valueUsd": "40000.000000", "pct": 40 },
    { "yieldSourceId": "morpho-gauntlet-usdc", "name": "Morpho Gauntlet USDC Prime", "valueUsd": "30000.000000", "pct": 30 },
    { "yieldSourceId": "morpho-steakhouse-usdc", "name": "Morpho Steakhouse USDC Prime", "valueUsd": "30000.000000", "pct": 30 }
  ]
}

5. Preview a withdrawal

curl -X POST "$BASE_URL/v2/wallets/$WALLET_ID/withdrawal-preview" \
  -H "Authorization: Bearer $GROUND_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "destinationChain": "polygon",
    "amountUsd": 65000
  }'
{
  "amountUsd": "65000.000000",
  "feeUsd": "0.000000",
  "availableUsd": "82500.000000",
  "availableToInitiateUsd": "82500.000000",
  "estimatedCompletionTime": "PT2H"
}

6. Initiate a withdrawal

curl -X POST "$BASE_URL/v2/wallets/$WALLET_ID/withdraw" \
  -H "Authorization: Bearer $GROUND_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "requestId": "df8b7be6-e110-4f6d-9b2d-7c44a5b1f0b0",
    "destinationChain": "ethereum",
    "amountUsd": 65000,
    "destinationAddress": "0x742d35Cc6634C0532925a3b844Bc454e4438f44e"
  }'

7. Track the withdrawal

Poll the withdrawal or subscribe to webhooks:
curl "$BASE_URL/v2/wallets/$WALLET_ID/withdrawals/$WITHDRAWAL_ID" \
  -H "Authorization: Bearer $GROUND_API_TOKEN"
The withdrawal moves through pending, processing, and a terminal status such as completed, failed, or cancelled. If approval is required, a payout leg enters pending_customer_approval with a turnkeyActivityId — see Transaction Approvals.

Next steps