Skip to main content
This page covers the conventions shared across all Portfolio Wallet API endpoints.

Authentication

All requests require a Bearer token in the Authorization header. If the token is missing or invalid, the API returns 401.
curl -X GET "https://sandbox.trybraid.xyz/v2/portfolio-wallets" \
  -H "Authorization: Bearer $BRAID_API_TOKEN"
{
  "portfolioWallets": [
    {
      "id": "9d1a1c83-3a1c-4c14-9c5a-0c9a57a4a7db",
      "label": "Treasury Portfolio",
      "blendedRateBps": 565,
      "status": "active",
      "globalWalletBalance": 82500,
      "depositAddresses": {
        "arbitrum": "0x21246509968c4d24611f414560971AEc2e3A079B",
        "ethereum": "0x21246509968c4d24611f414560971AEc2e3A079B"
      }
    }
  ],
  "nextCursor": null
}

Environments

EnvironmentBase URL
Sandboxhttps://sandbox.trybraid.xyz
Productionhttps://production.trybraid.xyz
Sandbox focuses on test networks while you integrate. Production processes live funds on supported chains. Swap the base URL without changing request shapes. Sandbox is limited to two networks for high-parity integration:
  • ethereum → Ethereum Sepolia
  • solana → Solana devnet
The API uses the canonical chain tokens (ethereum, solana) in both environments; sandbox maps them to testnets internally.

Pagination

List endpoints use cursor-based pagination with limit and cursor parameters.
curl -X GET "$BASE_URL/v2/portfolio-wallets/$WALLET_ID/withdrawals?limit=25" \
  -H "Authorization: Bearer $BRAID_API_TOKEN"
The response includes a nextCursor field. Pass it as cursor to fetch the next page:
curl -X GET "$BASE_URL/v2/portfolio-wallets/$WALLET_ID/withdrawals?limit=25&cursor=$NEXT_CURSOR" \
  -H "Authorization: Bearer $BRAID_API_TOKEN"
When nextCursor is null, you have reached the end of the result set. Additional query parameters on list endpoints:
  • sort: field to sort by (e.g. createdAt)
  • order: desc (default) or asc
  • createdAtGte: ISO-8601 timestamp filter
  • status: repeatable status filter (e.g. status=processing&status=completed)

Idempotency

Create and withdrawal endpoints accept a requestId (UUID v4). Retrying the same request with the same requestId returns the original response without creating duplicates. If the requestId was already used, the API returns 409 Conflict.
curl -X POST "$BASE_URL/v2/portfolio-wallets" \
  -H "Authorization: Bearer $BRAID_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "requestId": "f0a3afc3-1e67-4c0c-a8e1-3f5d8fb9a23b",
    "label": "Treasury Portfolio",
    "positions": [
      { "positionKey": "usdz", "targetWeightBps": 6000 },
      { "positionKey": "rlp", "targetWeightBps": 4000 }
    ]
  }'
409 response:
{
  "error": "Duplicate requestId",
  "code": "duplicate_request_id"
}
When you receive a 409, fetch the existing resource by requestId rather than retrying the create.

Error handling

Errors are returned as JSON with a human-readable error string and a machine-readable code field.
{
  "error": "Missing required fields: destinationAddress, withdrawalAmount, token, chain, requestId",
  "code": "validation_error"
}
HTTP statusMeaningAction
400Validation errorFix the request and retry
401Authentication failedCheck your Bearer token
404Resource not foundVerify the wallet/withdrawal ID
409Duplicate requestIdFetch the existing resource instead
500Server errorLog the response and retry with backoff
Use the code field for programmatic branching. Use the error string for logging and debugging.