Skip to main content
POST
/
v1
/
wallet
/
internal
/
withdraw
{
  "success": true
}

Overview

Withdraw funds from a custodial (internal) wallet to an external blockchain address. Specify the source wallet, destination address, amount, and currency. Withdrawals are processed on-chain and may require network confirmations. Use Cases:
  • Send funds to personal external wallet
  • Transfer to exchanges or other platforms
  • Withdraw to whitelisted addresses
  • Move funds between platforms
Prerequisites:
  • Source internal wallet must have sufficient balance
  • For some platforms, destination address may need to be whitelisted
  • User must have appropriate verification status

Authentication

x-client-key
string
required
Your public API client key
Authorization
string
required
Bearer token for authentication

Query Parameters

x-us-env
boolean
default:false
Route to US backend environment

Request Body

amount
string
required
Amount to withdraw (decimal string)
recipientAddrss
string
required
Destination blockchain address (Note: field name has typo in API)
recipientMemo
string
Memo/destination tag for recipient address (required for XRP, Stellar, etc.)
sourceAddress
string
required
Source wallet address (obtained from address field in GET /v1/wallet/internal)
sourceMemo
string
Source wallet memo (obtained from addressMemo field in GET /v1/wallet/internal)
currency
string
required
Currency code (e.g., “xrp”, “usdc”, “sol”)

Response

success
boolean
Whether withdrawal was initiated successfully
{
  "success": true
}

Code Examples

curl -X POST "https://dev.api.baanx.com/v1/wallet/internal/withdraw" \
  -H "x-client-key: YOUR_CLIENT_KEY" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": "10.5",
    "recipientAddrss": "rNxp4h8apvRis6mJf9Sh8C6iRxfrDWN7AA",
    "recipientMemo": "12345",
    "sourceAddress": "rPEPPER7kfTD9w2To4CQk6UCfuHM9c6GDY",
    "sourceMemo": "78",
    "currency": "xrp"
  }'

Complete Withdrawal Flow

1

Get Internal Wallets

Retrieve available internal wallets
const wallets = await fetch('/v1/wallet/internal')
  .then(r => r.json());
const xrpWallet = wallets.find(w => w.currency === 'xrp');
2

Validate Balance

Ensure sufficient balance for withdrawal
const balance = parseFloat(xrpWallet.balance);
const withdrawAmount = 10.5;

if (balance < withdrawAmount) {
  throw new Error('Insufficient balance');
}
3

Prepare Withdrawal Data

Collect all required information
const withdrawalData = {
  amount: withdrawAmount.toString(),
  recipientAddrss: 'rNxp4h8apvRis6mJf9Sh8C6iRxfrDWN7AA',
  recipientMemo: '12345',
  sourceAddress: xrpWallet.address,
  sourceMemo: xrpWallet.addressMemo,
  currency: xrpWallet.currency
};
4

Initiate Withdrawal

Execute the withdrawal request
const response = await fetch('/v1/wallet/internal/withdraw', {
  method: 'POST',
  body: JSON.stringify(withdrawalData)
});

const result = await response.json();
if (result.success) {
  console.log('Withdrawal initiated!');
}
5

Monitor Completion

Check wallet history for confirmation
setTimeout(async () => {
  const history = await fetch(
    `/v1/wallet/history?walletId=${xrpWallet.id}&walletType=INTERNAL&walletCurrency=${xrpWallet.currency}`
  ).then(r => r.json());

  const withdrawal = history.find(tx =>
    tx.sign === 'debit' &&
    tx.amount === withdrawAmount.toString()
  );

  if (withdrawal) {
    console.log('Withdrawal confirmed!');
  }
}, 5000);

Important Notes

Field Name Typo: The recipient address field is named recipientAddrss (missing an ‘e’). This is a known API quirk that must be used exactly as shown.
Source Address Fields: The sourceAddress corresponds to the address field and sourceMemo corresponds to the addressMemo field from the GET /v1/wallet/internal response.
Memo Requirements: For XRP, Stellar, and other memo-based networks, always include recipient memo if withdrawing to an exchange or custodial service. Missing memos can result in lost funds.

Error Handling

Common Errors

Insufficient Balance
{
  "message": "Insufficient balance for withdrawal"
}
Solution: Check balance before withdrawal and account for network fees. Invalid Address Format
{
  "message": "Invalid recipient address format"
}
Solution: Validate address format for the specific blockchain before submitting. Missing Memo
{
  "message": "Recipient memo required for this network"
}
Solution: Include recipientMemo for XRP, Stellar, and similar networks. Withdrawal Not Allowed
{
  "message": "Withdrawals temporarily disabled"
}
Solution: Check platform status or contact support. May be due to maintenance or security holds.

Address Validation

Validate addresses before withdrawal to prevent errors:
function validateAddress(address, currency) {
  const patterns = {
    xrp: /^r[1-9A-HJ-NP-Za-km-z]{25,34}$/,
    eth: /^0x[a-fA-F0-9]{40}$/,
    solana: /^[1-9A-HJ-NP-Za-km-z]{32,44}$/
  };

  const pattern = patterns[currency.toLowerCase()];

  if (!pattern) {
    throw new Error(`Validation pattern not found for ${currency}`);
  }

  if (!pattern.test(address)) {
    throw new Error(`Invalid ${currency.toUpperCase()} address format`);
  }

  return true;
}

try {
  validateAddress('rNxp4h8apvRis6mJf9Sh8C6iRxfrDWN7AA', 'xrp');
  console.log('Address is valid');
} catch (error) {
  console.error(error.message);
}

Edge Cases

Minimum Withdrawal Amounts

Networks may have minimum withdrawal thresholds:
const minimums = {
  xrp: 10,
  usdc: 1,
  eth: 0.01
};

if (parseFloat(amount) < minimums[currency]) {
  throw new Error(`Minimum withdrawal is ${minimums[currency]} ${currency.toUpperCase()}`);
}

Network Fees

Withdrawal amounts should account for network fees:
const balance = parseFloat(wallet.balance);
const estimatedFee = 0.1;
const maxWithdrawal = balance - estimatedFee;

console.log(`Maximum withdrawal: ${maxWithdrawal} ${wallet.currency.toUpperCase()}`);

Whitelist Requirements

Some configurations require whitelisted addresses:
const whitelistedAddresses = await fetch(
  `/v1/wallet/whitelist?currency=${currency}`
).then(r => r.json());

const isWhitelisted = whitelistedAddresses.some(
  w => w.walletAddress === recipientAddress
);

if (!isWhitelisted) {
  console.warn('Address not whitelisted. Withdrawal may fail.');
}