> ## Documentation Index
> Fetch the complete documentation index at: https://docs.baanx.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Manage Whitelisted Addresses

> Manage pre-approved external wallet addresses for secure withdrawals

## Overview

Whitelist management provides an additional security layer for withdrawals from internal (custodial) wallets. Whitelisted addresses are pre-approved withdrawal destinations that have been verified and saved for secure fund transfers.

**Security Benefits:**

* Pre-approve trusted addresses before withdrawal
* Prevent withdrawal to unauthorized addresses
* Maintain audit trail of approved destinations
* Track usage history of whitelisted addresses

**Use Cases:**

* Add frequently used exchange addresses
* Pre-approve personal wallet addresses
* Manage beneficiary addresses for business accounts
* Implement security policies requiring address approval

***

## GET - Retrieve Whitelisted Addresses

Get all whitelisted addresses for a specific currency.

### Authentication

<ParamField header="x-client-key" type="string" required>
  Your public API client key
</ParamField>

<ParamField header="Authorization" type="string" required>
  Bearer token for authentication
</ParamField>

### Query Parameters

<ParamField query="currency" type="string" required>
  Currency of the desired whitelisted addresses (e.g., "xrp", "usdc", "eth")
</ParamField>

<ParamField query="x-us-env" type="boolean" default={false}>
  Route to US backend environment
</ParamField>

### Response

<ResponseField name="id" type="string">
  Unique whitelist entry identifier
</ResponseField>

<ResponseField name="name" type="string">
  Friendly name or label for the address
</ResponseField>

<ResponseField name="beneficiaryFirstName" type="string">
  Beneficiary's first name
</ResponseField>

<ResponseField name="beneficiaryLastName" type="string">
  Beneficiary's last name
</ResponseField>

<ResponseField name="walletAddress" type="string">
  Blockchain address
</ResponseField>

<ResponseField name="walletMemo" type="string">
  Memo/destination tag (for XRP, Stellar, etc.)
</ResponseField>

<ResponseField name="currency" type="string">
  Currency code
</ResponseField>

<ResponseField name="lastUsedAt" type="string">
  ISO 8601 timestamp of last withdrawal to this address
</ResponseField>

<ResponseField name="createdAt" type="string">
  ISO 8601 timestamp of when address was whitelisted
</ResponseField>

<ResponseExample>
  ```json 200 - Success theme={null}
  [
    {
      "id": "d7ed0d12-270c-4491-b1a4-bebf2cc42b5c",
      "name": "Binance Account | Primary",
      "beneficiaryFirstName": "John",
      "beneficiaryLastName": "Doe",
      "walletAddress": "rNxp4h8apvRis6mJf9Sh8C6iRxfrDWN7AA",
      "walletMemo": "66",
      "currency": "xrp",
      "lastUsedAt": "2025-08-12T13:44:47.287Z",
      "createdAt": "2025-08-11T13:44:47.287Z"
    },
    {
      "id": "a3f2e1d4-c5b6-47a8-9e0f-1d2c3b4a5e6f",
      "name": "Kraken Exchange",
      "beneficiaryFirstName": "John",
      "beneficiaryLastName": "Doe",
      "walletAddress": "rPEPPER7kfTD9w2To4CQk6UCfuHM9c6GDY",
      "walletMemo": "12345",
      "currency": "xrp",
      "lastUsedAt": null,
      "createdAt": "2025-08-10T10:30:22.123Z"
    }
  ]
  ```

  ```json 401 - Authentication Error theme={null}
  {
    "message": "Not authenticated"
  }
  ```

  ```json 422 - Validation Error theme={null}
  {
    "message": "currency parameter is required"
  }
  ```
</ResponseExample>

<CodeGroup>
  ```bash cURL theme={null}
  curl -X GET "https://dev.api.baanx.com/v1/wallet/whitelist?currency=xrp" \
    -H "x-client-key: YOUR_CLIENT_KEY" \
    -H "Authorization: Bearer YOUR_ACCESS_TOKEN"
  ```

  ```python Python theme={null}
  import requests

  url = "https://dev.api.baanx.com/v1/wallet/whitelist"
  headers = {
      "x-client-key": "YOUR_CLIENT_KEY",
      "Authorization": "Bearer YOUR_ACCESS_TOKEN"
  }

  params = {"currency": "xrp"}
  response = requests.get(url, headers=headers, params=params)
  whitelisted = response.json()

  print(f"Whitelisted XRP addresses: {len(whitelisted)}")

  for address in whitelisted:
      print(f"\n{address['name']}")
      print(f"  Address: {address['walletAddress']}")
      if address['walletMemo']:
          print(f"  Memo: {address['walletMemo']}")
      print(f"  Beneficiary: {address['beneficiaryFirstName']} {address['beneficiaryLastName']}")
      if address['lastUsedAt']:
          print(f"  Last used: {address['lastUsedAt']}")
  ```

  ```typescript TypeScript theme={null}
  interface WhitelistedAddress {
    id: string;
    name: string;
    beneficiaryFirstName: string;
    beneficiaryLastName: string;
    walletAddress: string;
    walletMemo: string | null;
    currency: string;
    lastUsedAt: string | null;
    createdAt: string;
  }

  async function getWhitelistedAddresses(
    currency: string
  ): Promise<WhitelistedAddress[]> {
    const response = await fetch(
      `https://dev.api.baanx.com/v1/wallet/whitelist?currency=${currency}`,
      {
        headers: {
          'x-client-key': 'YOUR_CLIENT_KEY',
          'Authorization': 'Bearer YOUR_ACCESS_TOKEN'
        }
      }
    );

    return await response.json();
  }

  const xrpAddresses = await getWhitelistedAddresses('xrp');
  console.log(`Found ${xrpAddresses.length} whitelisted XRP addresses`);
  ```
</CodeGroup>

***

## POST - Add Addresses to Whitelist

Add one or more external wallet addresses to the whitelist. Multiple addresses can be added in a single request.

### Request Body

<ParamField body="wallets" type="array" required>
  Array of addresses to whitelist

  <Expandable title="Whitelist Entry Object">
    <ParamField body="currency" type="string" required>
      Currency code (e.g., "xrp", "usdc")
    </ParamField>

    <ParamField body="name" type="string" required>
      Friendly name or label for the address
    </ParamField>

    <ParamField body="beneficiaryFirstName" type="string" required>
      Beneficiary's first name
    </ParamField>

    <ParamField body="beneficiaryLastName" type="string" required>
      Beneficiary's last name
    </ParamField>

    <ParamField body="walletAddress" type="string" required>
      Blockchain address
    </ParamField>

    <ParamField body="walletMemo" type="string">
      Memo/destination tag (required for XRP, Stellar, etc.)
    </ParamField>
  </Expandable>
</ParamField>

### Response

<ResponseField name="success" type="boolean">
  Whether whitelisting was successful
</ResponseField>

<ResponseExample>
  ```json 201 - Created theme={null}
  {
    "success": true
  }
  ```

  ```json 422 - Validation Error theme={null}
  {
    "message": "Invalid wallet address format"
  }
  ```
</ResponseExample>

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST "https://dev.api.baanx.com/v1/wallet/whitelist" \
    -H "x-client-key: YOUR_CLIENT_KEY" \
    -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
    -H "Content-Type: application/json" \
    -d '{
      "wallets": [
        {
          "currency": "xrp",
          "name": "Binance Account | Primary",
          "beneficiaryFirstName": "John",
          "beneficiaryLastName": "Doe",
          "walletAddress": "rNxp4h8apvRis6mJf9Sh8C6iRxfrDWN7AA",
          "walletMemo": "66"
        }
      ]
    }'
  ```

  ```python Python theme={null}
  import requests

  url = "https://dev.api.baanx.com/v1/wallet/whitelist"
  headers = {
      "x-client-key": "YOUR_CLIENT_KEY",
      "Authorization": "Bearer YOUR_ACCESS_TOKEN",
      "Content-Type": "application/json"
  }

  data = {
      "wallets": [
          {
              "currency": "xrp",
              "name": "Binance Account | Primary",
              "beneficiaryFirstName": "John",
              "beneficiaryLastName": "Doe",
              "walletAddress": "rNxp4h8apvRis6mJf9Sh8C6iRxfrDWN7AA",
              "walletMemo": "66"
          },
          {
              "currency": "xrp",
              "name": "Kraken Exchange",
              "beneficiaryFirstName": "John",
              "beneficiaryLastName": "Doe",
              "walletAddress": "rPEPPER7kfTD9w2To4CQk6UCfuHM9c6GDY",
              "walletMemo": "12345"
          }
      ]
  }

  response = requests.post(url, headers=headers, json=data)

  if response.status_code == 201:
      print("Addresses added to whitelist successfully!")
  ```

  ```typescript TypeScript theme={null}
  interface AddWhitelistRequest {
    currency: string;
    name: string;
    beneficiaryFirstName: string;
    beneficiaryLastName: string;
    walletAddress: string;
    walletMemo?: string;
  }

  async function addToWhitelist(
    addresses: AddWhitelistRequest[]
  ): Promise<boolean> {
    const response = await fetch(
      'https://dev.api.baanx.com/v1/wallet/whitelist',
      {
        method: 'POST',
        headers: {
          'x-client-key': 'YOUR_CLIENT_KEY',
          'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({ wallets: addresses })
      }
    );

    const result = await response.json();
    return result.success;
  }

  await addToWhitelist([
    {
      currency: 'xrp',
      name: 'Binance Account',
      beneficiaryFirstName: 'John',
      beneficiaryLastName: 'Doe',
      walletAddress: 'rNxp4h8apvRis6mJf9Sh8C6iRxfrDWN7AA',
      walletMemo: '66'
    }
  ]);
  ```
</CodeGroup>

***

## DELETE - Remove Addresses from Whitelist

Remove previously whitelisted addresses. Provide one or more whitelist entry IDs to remove.

### Request Body

<ParamField body="walletIds" type="array" required>
  Array of whitelist entry IDs to remove (obtained from GET response)
</ParamField>

### Response

<ResponseField name="success" type="boolean">
  Whether removal was successful
</ResponseField>

<ResponseExample>
  ```json 200 - Success theme={null}
  {
    "success": true
  }
  ```

  ```json 422 - Validation Error theme={null}
  {
    "message": "Invalid wallet ID"
  }
  ```
</ResponseExample>

<CodeGroup>
  ```bash cURL theme={null}
  curl -X DELETE "https://dev.api.baanx.com/v1/wallet/whitelist" \
    -H "x-client-key: YOUR_CLIENT_KEY" \
    -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
    -H "Content-Type: application/json" \
    -d '{
      "walletIds": [
        "d7ed0d12-270c-4491-b1a4-bebf2cc42b5c"
      ]
    }'
  ```

  ```python Python theme={null}
  remove_data = {
      "walletIds": [
          "d7ed0d12-270c-4491-b1a4-bebf2cc42b5c",
          "a3f2e1d4-c5b6-47a8-9e0f-1d2c3b4a5e6f"
      ]
  }

  response = requests.delete(
      "https://dev.api.baanx.com/v1/wallet/whitelist",
      headers=headers,
      json=remove_data
  )

  if response.status_code == 200:
      print("Addresses removed from whitelist")
  ```

  ```typescript TypeScript theme={null}
  async function removeFromWhitelist(walletIds: string[]): Promise<boolean> {
    const response = await fetch(
      'https://dev.api.baanx.com/v1/wallet/whitelist',
      {
        method: 'DELETE',
        headers: {
          'x-client-key': 'YOUR_CLIENT_KEY',
          'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({ walletIds })
      }
    );

    const result = await response.json();
    return result.success;
  }

  await removeFromWhitelist(['d7ed0d12-270c-4491-b1a4-bebf2cc42b5c']);
  ```
</CodeGroup>

***

## Complete Whitelist Management

<CodeGroup>
  ```javascript Full Management Flow theme={null}
  async function manageWhitelist(currency) {
    const current = await fetch(
      `/v1/wallet/whitelist?currency=${currency}`
    ).then(r => r.json());

    console.log(`Current whitelist: ${current.length} addresses`);

    const newAddress = {
      currency,
      name: 'New Exchange Account',
      beneficiaryFirstName: 'John',
      beneficiaryLastName: 'Doe',
      walletAddress: 'rNewAddress123456789',
      walletMemo: '999'
    };

    const exists = current.some(
      w => w.walletAddress === newAddress.walletAddress &&
           w.walletMemo === newAddress.walletMemo
    );

    if (!exists) {
      await fetch('/v1/wallet/whitelist', {
        method: 'POST',
        body: JSON.stringify({ wallets: [newAddress] })
      });
      console.log('Address added to whitelist');
    } else {
      console.log('Address already whitelisted');
    }

    const unusedAddresses = current.filter(w => !w.lastUsedAt);
    if (unusedAddresses.length > 0) {
      console.log(`${unusedAddresses.length} addresses never used`);
    }

    return await fetch(`/v1/wallet/whitelist?currency=${currency}`)
      .then(r => r.json());
  }
  ```
</CodeGroup>

## Important Notes

<Warning>
  **Memo Requirements**: For networks like XRP and Stellar, the combination of address + memo identifies the destination. Always include both when whitelisting exchange addresses.
</Warning>

<Note>
  **Usage Tracking**: The `lastUsedAt` field helps identify frequently vs rarely used addresses. Consider removing unused addresses periodically.
</Note>

<Tip>
  **Descriptive Names**: Use clear, descriptive names that help identify the purpose and destination of each whitelisted address (e.g., "Binance Main Account | Trading").
</Tip>

## Address Validation

<CodeGroup>
  ```javascript Validate Before Whitelisting theme={null}
  function validateWhitelistEntry(entry) {
    const addressPatterns = {
      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 = addressPatterns[entry.currency];
    if (!pattern) {
      throw new Error(`Unsupported currency: ${entry.currency}`);
    }

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

    if (!entry.name || entry.name.trim().length < 3) {
      throw new Error('Name must be at least 3 characters');
    }

    if (!entry.beneficiaryFirstName || !entry.beneficiaryLastName) {
      throw new Error('Beneficiary name is required');
    }

    const memoRequired = ['xrp', 'xlm'].includes(entry.currency);
    if (memoRequired && !entry.walletMemo) {
      console.warn(`Memo recommended for ${entry.currency.toUpperCase()}`);
    }

    return true;
  }
  ```
</CodeGroup>

## Use Cases

### Import from CSV

```javascript theme={null}
async function importWhitelistFromCSV(csvData, currency) {
  const lines = csvData.split('\n').slice(1);

  const addresses = lines.map(line => {
    const [name, firstName, lastName, address, memo] = line.split(',');
    return {
      currency,
      name: name.trim(),
      beneficiaryFirstName: firstName.trim(),
      beneficiaryLastName: lastName.trim(),
      walletAddress: address.trim(),
      walletMemo: memo?.trim() || undefined
    };
  });

  return await addToWhitelist(addresses);
}
```

### Check if Address is Whitelisted

```javascript theme={null}
async function isAddressWhitelisted(address, currency, memo = null) {
  const whitelist = await getWhitelistedAddresses(currency);

  return whitelist.some(
    w => w.walletAddress === address &&
         (memo === null || w.walletMemo === memo)
  );
}

const isWhitelisted = await isAddressWhitelisted(
  'rNxp4h8apvRis6mJf9Sh8C6iRxfrDWN7AA',
  'xrp',
  '66'
);
```

### Clean Up Unused Addresses

```javascript theme={null}
async function removeUnusedAddresses(currency, daysUnused = 90) {
  const whitelist = await getWhitelistedAddresses(currency);
  const cutoffDate = new Date();
  cutoffDate.setDate(cutoffDate.getDate() - daysUnused);

  const toRemove = whitelist.filter(w => {
    if (!w.lastUsedAt) return false;

    const lastUsed = new Date(w.lastUsedAt);
    return lastUsed < cutoffDate;
  });

  if (toRemove.length > 0) {
    const ids = toRemove.map(w => w.id);
    await removeFromWhitelist(ids);
    console.log(`Removed ${ids.length} unused addresses`);
  }
}
```

## Edge Cases

### Duplicate Addresses

Attempting to whitelist an already-whitelisted address:

```javascript theme={null}
const whitelist = await getWhitelistedAddresses('xrp');
const isDuplicate = whitelist.some(
  w => w.walletAddress === newAddress && w.walletMemo === newMemo
);

if (isDuplicate) {
  console.log('Address already whitelisted');
}
```

### Maximum Whitelist Size

Platforms may impose limits on whitelist size. Check current count:

```javascript theme={null}
const MAX_WHITELIST_SIZE = 100;

const current = await getWhitelistedAddresses(currency);
if (current.length >= MAX_WHITELIST_SIZE) {
  throw new Error('Whitelist limit reached. Remove unused addresses first.');
}
```

## Related Endpoints

* [Withdraw from Internal Wallet](/api-reference/wallet/internal-withdraw) - Use whitelisted addresses for secure withdrawals
* [Get Internal Wallets](/api-reference/wallet/internal) - View internal wallets that can withdraw to whitelist
