v1

latestOpenAPI 3.0.32026-08-041747125.8 KB
Withdrawals

Create a withdrawal

Source of Funds — Rebalancer Contract Pool Balance

Withdrawals move tokens from a pool held by the user's rebalancer contract back to the user's wallet. The funds are NOT in the user's wallet — they are already inside the DeFi protocol (Aave, Morpho, or Euler) deposited by the rebalancer.

The chain, token, poolContract, and available amount must all be derived from GET /v1/balances/{walletAddress} — do not guess or hardcode these values.

How to build a withdrawal request from the balances response

  1. Call GET /v1/balances/{walletAddress} to get the rebalancer's holdings.
  2. Navigate to: perToken[n].perChain[m].perProtocol[p].perPool[q]
  3. From the pool object:
    • chain field → use as chain in the withdrawal request
    • poolAddress field → use as poolContract in the withdrawal request
    • balanceRaw field → maximum withdrawable amount (raw units)
    • withdrawRequest field → pre-filled EIP-712 domain, types, and value for signing
  4. The withdrawRequest.value contains token (token contract address) and poolContract (pool address) — use these as the signing value.
  5. Supply amount (≤ balanceRaw, ≥ minimum) and deadline (unix timestamp, max 1 minute in future).
  6. Sign the EIP-712 typed data using the domain/types/value from withdrawRequest.
  7. Submit this endpoint with all fields.

Field-by-field mapping from balances response to WithdrawalRequest

WithdrawalRequest fieldSource
chainPoolBalance.chain (string, e.g. "BASE")
tokenParent token key/symbol (e.g. "USDC") — NOT withdrawRequest.value.token which is a contract address
walletAddressThe user's wallet address (same as used in JWT)
poolContractPoolBalance.poolAddress
amountUser-chosen raw amount, ≤ PoolBalance.balanceRaw, ≥ 100000 for USDC
deadlineUser-chosen unix timestamp, max 60 seconds from now
signatureEIP-712 sign of withdrawRequest.domain + withdrawRequest.types + {token: withdrawRequest.value.token, poolContract: withdrawRequest.value.poolContract, amount: <your_amount>, deadline: <your_deadline>}

Initiates a withdrawal transaction from DeFi protocols.

Initiates a withdrawal transaction from DeFi protocols.

Withdrawal must be signed as per EIP-712 Typed structured data hashing and signing. The signature must be created by wallet.

Signature relevant information is retrieved by /v1/balances/{walletAddress} endpoint in the withdrawRequest field. EIP 712 domain parameters and types are provided for convenience. The value field contains the token (address) and poolContract (address) that must match the withdrawal request, while amount and deadline must be supplied by the user.

Deadline must be a unix timestamp no more than 1 minute in the future which is the maximum amount of time the server waits for transaction confirmation.

Amount must be at least 0.1 (stablecoin) of the token to cover on-behalf transaction gas fees and no more than the available balance in the specified pool. This value is specified in raw units (e.g., 6 decimals for USDC). Token decimals are included in the token object of /v1/balances/{walletAddress} endpoint for reference.

Signature must be a 0x-prefixed hex string signed by the wallet address associated with the JWT token. For a standard EOA wallet this is 132 characters (0x + 130 hex characters). Smart contract wallets are also supported (e.g. multisig, passkey wallets) via EIP-1271 (isValidSignature) verification, so the signature may be longer than 132 characters in that case — up to a maximum of 4096 hex characters.

Rate limiting: 1 request per 3 seconds per client IP. Excess requests receive HTTP 429 with Retry-After, X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset headers (see RateLimitExceeded response).

post/v1/withdrawals

Request body

chain'ETHEREUM' | 'BASE' | 'POLYGON' | 'ARBITRUM' | 'OPTIMISM' | 'AVALANCHE' | 'LINEA' required

The blockchain network where the user's funds are located. Must match the chain returned in GET /v1/balances/{walletAddress}. The chain where the rebalancer holds funds in the specified pool. Must match the chain field of the pool from GET /v1/balances/{walletAddress} perToken.perChain.perProtocol.perPool. Do NOT use the user's wallet chain — this is the chain the rebalancer deposited into, which may be different. This value must be taken directly from PoolBalance.chain — do NOT convert from wagmi chain names. Use withdrawRequest.domain.chainId (integer) to switch the wallet chain before signing.

token'USDC' | 'MUSD' | 'USDT' | 'RLUSD' | 'USDG' | 'USDE' | 'PYUSD' required

Token symbol (uppercase). Use the symbol (e.g. "USDC"), NOT the contract address. Do NOT use withdrawRequest.value.token here — that is the ERC-20 contract address used only for EIP-712 signing. This field must be the human-readable symbol from the parent token level of GET /v1/balances/{walletAddress}.

walletAddressstring required

User's Ethereum wallet address (must be checksummed per EIP-55)

amountstring required

Amount in token's smallest unit (minimum 0.1 to cover gas fees)

deadlinestring required

Unix timestamp deadline for withdrawal (max 1 minute in future)

signaturestring required

EIP-712 signature for withdrawal authorization. 130 hex characters (0x + 130) for a standard EOA wallet; smart contract wallets (EIP-1271, e.g. multisig, passkey wallets) may produce longer signatures, up to 4096 hex characters.

poolContractstring required

Pool contract address to withdraw from (must be checksummed per EIP-55)

Example request

{
  "amount": "500000",
  "deadline": "1700000100"
}

Response

Withdrawal initiated successfully

trackingIdstring uuid required

Tracking ID (UUID) returned from withdrawal creation

Example response

{
  "trackingId": "550e8400-e29b-41d4-a716-446655440000"
}