curl --request POST \
--url https://sandbox.groundtech.co/v2/wallets \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"requestId": "a1b2c3d4-0000-4000-8000-000000000001",
"label": "Corporate Treasury",
"autoRebalance": true,
"strategy": {
"allocations": {
"usdc": [
{
"yieldSourceId": "cash",
"pct": 20
},
{
"yieldSourceId": "morpho-gauntlet-usdc",
"pct": 80
}
],
"usdt": [
{
"yieldSourceId": "cash",
"pct": 100
}
]
}
}
}
'import requests
url = "https://sandbox.groundtech.co/v2/wallets"
payload = {
"requestId": "a1b2c3d4-0000-4000-8000-000000000001",
"label": "Corporate Treasury",
"autoRebalance": True,
"strategy": { "allocations": {
"usdc": [
{
"yieldSourceId": "cash",
"pct": 20
},
{
"yieldSourceId": "morpho-gauntlet-usdc",
"pct": 80
}
],
"usdt": [
{
"yieldSourceId": "cash",
"pct": 100
}
]
} }
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
requestId: 'a1b2c3d4-0000-4000-8000-000000000001',
label: 'Corporate Treasury',
autoRebalance: true,
strategy: {
allocations: {
usdc: [
{yieldSourceId: 'cash', pct: 20},
{yieldSourceId: 'morpho-gauntlet-usdc', pct: 80}
],
usdt: [{yieldSourceId: 'cash', pct: 100}]
}
}
})
};
fetch('https://sandbox.groundtech.co/v2/wallets', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://sandbox.groundtech.co/v2/wallets",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'requestId' => 'a1b2c3d4-0000-4000-8000-000000000001',
'label' => 'Corporate Treasury',
'autoRebalance' => true,
'strategy' => [
'allocations' => [
'usdc' => [
[
'yieldSourceId' => 'cash',
'pct' => 20
],
[
'yieldSourceId' => 'morpho-gauntlet-usdc',
'pct' => 80
]
],
'usdt' => [
[
'yieldSourceId' => 'cash',
'pct' => 100
]
]
]
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://sandbox.groundtech.co/v2/wallets"
payload := strings.NewReader("{\n \"requestId\": \"a1b2c3d4-0000-4000-8000-000000000001\",\n \"label\": \"Corporate Treasury\",\n \"autoRebalance\": true,\n \"strategy\": {\n \"allocations\": {\n \"usdc\": [\n {\n \"yieldSourceId\": \"cash\",\n \"pct\": 20\n },\n {\n \"yieldSourceId\": \"morpho-gauntlet-usdc\",\n \"pct\": 80\n }\n ],\n \"usdt\": [\n {\n \"yieldSourceId\": \"cash\",\n \"pct\": 100\n }\n ]\n }\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://sandbox.groundtech.co/v2/wallets")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"requestId\": \"a1b2c3d4-0000-4000-8000-000000000001\",\n \"label\": \"Corporate Treasury\",\n \"autoRebalance\": true,\n \"strategy\": {\n \"allocations\": {\n \"usdc\": [\n {\n \"yieldSourceId\": \"cash\",\n \"pct\": 20\n },\n {\n \"yieldSourceId\": \"morpho-gauntlet-usdc\",\n \"pct\": 80\n }\n ],\n \"usdt\": [\n {\n \"yieldSourceId\": \"cash\",\n \"pct\": 100\n }\n ]\n }\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://sandbox.groundtech.co/v2/wallets")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"requestId\": \"a1b2c3d4-0000-4000-8000-000000000001\",\n \"label\": \"Corporate Treasury\",\n \"autoRebalance\": true,\n \"strategy\": {\n \"allocations\": {\n \"usdc\": [\n {\n \"yieldSourceId\": \"cash\",\n \"pct\": 20\n },\n {\n \"yieldSourceId\": \"morpho-gauntlet-usdc\",\n \"pct\": 80\n }\n ],\n \"usdt\": [\n {\n \"yieldSourceId\": \"cash\",\n \"pct\": 100\n }\n ]\n }\n }\n}"
response = http.request(request)
puts response.read_bodyCreate a portfolio wallet
Creates a wallet with or without automatic rebalancing. When autoRebalance is true, each stablecoin strategy group must sum to 100 percent. When it is false, deposits remain as cash until explicitly allocated. Existing requests that provide strategy without autoRebalance continue to enable automatic rebalancing. Idempotent on requestId — if a wallet with the same requestId already exists, the existing wallet is returned. Always returns 200; newly created wallets are returned with status: creating while they provision.
curl --request POST \
--url https://sandbox.groundtech.co/v2/wallets \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"requestId": "a1b2c3d4-0000-4000-8000-000000000001",
"label": "Corporate Treasury",
"autoRebalance": true,
"strategy": {
"allocations": {
"usdc": [
{
"yieldSourceId": "cash",
"pct": 20
},
{
"yieldSourceId": "morpho-gauntlet-usdc",
"pct": 80
}
],
"usdt": [
{
"yieldSourceId": "cash",
"pct": 100
}
]
}
}
}
'import requests
url = "https://sandbox.groundtech.co/v2/wallets"
payload = {
"requestId": "a1b2c3d4-0000-4000-8000-000000000001",
"label": "Corporate Treasury",
"autoRebalance": True,
"strategy": { "allocations": {
"usdc": [
{
"yieldSourceId": "cash",
"pct": 20
},
{
"yieldSourceId": "morpho-gauntlet-usdc",
"pct": 80
}
],
"usdt": [
{
"yieldSourceId": "cash",
"pct": 100
}
]
} }
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
requestId: 'a1b2c3d4-0000-4000-8000-000000000001',
label: 'Corporate Treasury',
autoRebalance: true,
strategy: {
allocations: {
usdc: [
{yieldSourceId: 'cash', pct: 20},
{yieldSourceId: 'morpho-gauntlet-usdc', pct: 80}
],
usdt: [{yieldSourceId: 'cash', pct: 100}]
}
}
})
};
fetch('https://sandbox.groundtech.co/v2/wallets', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://sandbox.groundtech.co/v2/wallets",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'requestId' => 'a1b2c3d4-0000-4000-8000-000000000001',
'label' => 'Corporate Treasury',
'autoRebalance' => true,
'strategy' => [
'allocations' => [
'usdc' => [
[
'yieldSourceId' => 'cash',
'pct' => 20
],
[
'yieldSourceId' => 'morpho-gauntlet-usdc',
'pct' => 80
]
],
'usdt' => [
[
'yieldSourceId' => 'cash',
'pct' => 100
]
]
]
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://sandbox.groundtech.co/v2/wallets"
payload := strings.NewReader("{\n \"requestId\": \"a1b2c3d4-0000-4000-8000-000000000001\",\n \"label\": \"Corporate Treasury\",\n \"autoRebalance\": true,\n \"strategy\": {\n \"allocations\": {\n \"usdc\": [\n {\n \"yieldSourceId\": \"cash\",\n \"pct\": 20\n },\n {\n \"yieldSourceId\": \"morpho-gauntlet-usdc\",\n \"pct\": 80\n }\n ],\n \"usdt\": [\n {\n \"yieldSourceId\": \"cash\",\n \"pct\": 100\n }\n ]\n }\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://sandbox.groundtech.co/v2/wallets")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"requestId\": \"a1b2c3d4-0000-4000-8000-000000000001\",\n \"label\": \"Corporate Treasury\",\n \"autoRebalance\": true,\n \"strategy\": {\n \"allocations\": {\n \"usdc\": [\n {\n \"yieldSourceId\": \"cash\",\n \"pct\": 20\n },\n {\n \"yieldSourceId\": \"morpho-gauntlet-usdc\",\n \"pct\": 80\n }\n ],\n \"usdt\": [\n {\n \"yieldSourceId\": \"cash\",\n \"pct\": 100\n }\n ]\n }\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://sandbox.groundtech.co/v2/wallets")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"requestId\": \"a1b2c3d4-0000-4000-8000-000000000001\",\n \"label\": \"Corporate Treasury\",\n \"autoRebalance\": true,\n \"strategy\": {\n \"allocations\": {\n \"usdc\": [\n {\n \"yieldSourceId\": \"cash\",\n \"pct\": 20\n },\n {\n \"yieldSourceId\": \"morpho-gauntlet-usdc\",\n \"pct\": 80\n }\n ],\n \"usdt\": [\n {\n \"yieldSourceId\": \"cash\",\n \"pct\": 100\n }\n ]\n }\n }\n}"
response = http.request(request)
puts response.read_bodyAuthorizations
Bearer authentication header of the form Bearer <token>, where <token> is your auth token.
Body
Response
Wallet returned. New wallets may still be provisioning with status: creating.
Whether Ground automatically deploys deposits and maintains the wallet's percentage targets.
Percentage targets when automatic rebalancing is enabled. Always null when it is disabled.
Show child attributes
Show child attributes
Compact wallet lifecycle and active-workflow status.
creating, idle, withdrawal_active, rebalance_active, withdrawal_and_rebalance_active, failed Deposit addresses keyed by chain. Sandbox wallets use ethereum_sepolia and solana_devnet; production wallets use arbitrum, base, ethereum, polygon, and solana.
Show child attributes
Show child attributes
{ "arbitrum": "0xAbC1230000000000000000000000000000000001", "base": "0xAbC1230000000000000000000000000000000001", "ethereum": "0xAbC1230000000000000000000000000000000001", "polygon": "0xAbC1230000000000000000000000000000000001", "solana": "7vFgKxM3bP4oEFbqkPmA5E2rYJ8HqKz8abc1" }
Show child attributes
Show child attributes
Show child attributes
Show child attributes