# Create Receive Addresses

Source: https://developers.bitgo.com/docs/custody-starter-architecture-receive-addresses

## Overview

Create unique receive addresses for each individual or entity in your enterprise. Using unique addresses for each customer or transaction improves privacy, simplifies accounting, and makes it easier to track deposits.

In the custody starter architecture, receive addresses are typically created on the deposit/withdraw wallet since this is where customer deposits arrive. However, you can create addresses on any wallet in your architecture.

## Prerequisites

- [Get Started](/docs/get-started-intro)
- [Set Up Deposit/Withdraw Wallet](/docs/custody-starter-architecture-deposit-withdraw-wallet)

## Cookbook

Need just the steps? Expand the cookbook below to get started:

<Cookbook slug="custody-starter-architecture-create-receive-addresses" title="Create Receive Addresses" />

## Create Receive Address

Create a new receive address on your deposit/withdraw wallet. You can create unlimited addresses for a wallet.

>Endpoint: [Create Address](/reference/v2walletnewaddress)

```shell cURL
export COIN="<ASSET_ID>"
export WALLET_ID="<DEPOSIT_WITHDRAW_WALLET_ID>"
export ACCESS_TOKEN="<YOUR_ACCESS_TOKEN>"
export LABEL="Customer ABC"

curl -X POST \
  "https://app.bitgo-test.com/api/v2/$COIN/wallet/$WALLET_ID/address" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -d '{
    "label": "'"$LABEL"'"
  }'
```
```js JavaScript
const { BitGo } = require('bitgo');

const accessToken = '<YOUR_ACCESS_TOKEN>';

const bitgo = new BitGo({
  accessToken: accessToken,
  env: 'prod',
});

async function createReceiveAddress() {
  const wallet = await bitgo.coin('<ASSET_ID>').wallets().get({
    id: '<DEPOSIT_WITHDRAW_WALLET_ID>'
  });

  const address = await wallet.createAddress({
    label: 'Customer ABC'
  });

  console.log('New Receive Address Created:');
  console.log('Address:', address.address);
  console.log('Label:', address.label);
  console.log('Address ID:', address.id);
}

createReceiveAddress();
```

#### Step Result

```json
{
  "id": "631283e10e052800066295e210da142a",
  "address": "bc1q8w3mcwt83tpmmr4reas3xt8t7rcshu7gztszew",
  "chain": 10,
  "index": 2,
  "coin": "btc",
  "wallet": "7849948ac0623f81f74f63dbd8351d5g",
  "label": "Customer ABC",
  "coinSpecific": {
    "redeemScript": "...",
    "witnessScript": "..."
  },
  "addressType": "p2shP2wsh"
}
```

>📘 **Note**
>
>Some networks, such as Ethereum, do not immediately return a new multisignature address, since creating a new address requires a blockchain transaction. The blockchain must confirm this transaction before you can use the address. The parameter `pendingChainInitialization` identifies if an address is awaiting confirmation.

## Create Multiple Addresses

For bulk onboarding, create multiple addresses programmatically.

```js JavaScript
const { BitGo } = require('bitgo');

const accessToken = '<YOUR_ACCESS_TOKEN>';

const bitgo = new BitGo({
  accessToken: accessToken,
  env: 'prod',
});

async function createAddressesForCustomers(customerList) {
  const wallet = await bitgo.coin('<ASSET_ID>').wallets().get({
    id: '<DEPOSIT_WITHDRAW_WALLET_ID>'
  });

  const addresses = [];

  for (const customer of customerList) {
    const address = await wallet.createAddress({
      label: `Customer ${customer.id} - ${customer.name}`
    });

    addresses.push({
      customerId: customer.id,
      customerName: customer.name,
      address: address.address,
      addressId: address.id
    });

    console.log(`Created address for ${customer.name}: ${address.address}`);
  }

  return addresses;
}

// Example usage
const customers = [
  { id: '001', name: 'Alice' },
  { id: '002', name: 'Bob' },
  { id: '003', name: 'Charlie' }
];

createAddressesForCustomers(customers);
```

## List Wallet Addresses

View all addresses created for a wallet.

>Endpoint: [List Addresses](/reference/v2walletaddresses)

```shell cURL
export COIN="<ASSET_ID>"
export WALLET_ID="<WALLET_ID>"
export ACCESS_TOKEN="<YOUR_ACCESS_TOKEN>"

curl -X GET \
  "https://app.bitgo-test.com/api/v2/$COIN/wallet/$WALLET_ID/addresses" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $ACCESS_TOKEN"
```
```js JavaScript
const wallet = await bitgo.coin('<ASSET_ID>').wallets().get({ id: '<WALLET_ID>' });
const addresses = await wallet.addresses();

console.log('Wallet Addresses:');
addresses.addresses.forEach(addr => {
  console.log(`  ${addr.label || 'No label'}: ${addr.address}`);
});
```

#### Step Result

```json
{
  "coin": "btc",
  "totalAddressCount": 5,
  "addresses": [
    {
      "id": "631283e10e052800066295e210da142a",
      "address": "bc1q8w3mcwt83tpmmr4reas3xt8t7rcshu7gztszew",
      "chain": 10,
      "index": 0,
      "coin": "btc",
      "wallet": "7849948ac0623f81f74f63dbd8351d5g",
      "label": "Default Receive Address"
    },
    {
      "id": "631283e10e052800066295e210da142b",
      "address": "bc1p...",
      "chain": 10,
      "index": 1,
      "coin": "btc",
      "wallet": "7849948ac0623f81f74f63dbd8351d5g",
      "label": "Customer ABC"
    },
    {
      "id": "631283e10e052800066295e210da142c",
      "address": "bc1q...",
      "chain": 10,
      "index": 2,
      "coin": "btc",
      "wallet": "7849948ac0623f81f74f63dbd8351d5g",
      "label": "Customer 002 - Bob"
    }
  ]
}
```

## Address Considerations

### UTXO-Based Assets (BTC, LTC, etc.)

- Funds received at any address are immediately spendable from the wallet.
- No consolidation required.
- Each address can receive unlimited transactions.

### Account-Based Assets (ETH, MATIC, etc.)

- Funds received at sub-addresses must be consolidated to the base address before spending.
- Consider gas costs when consolidating.
- See [Consolidate Account Balance](/docs/wallets-consolidate) for details.

### Address Labeling Best Practices

- Use descriptive labels that identify the customer or purpose.
- Include customer IDs for easy database correlation.
- Avoid storing sensitive personal information in labels.

## Webhooks for Deposit Monitoring

Configure webhooks to receive notifications when deposits arrive at your addresses. This enables automated deposit processing.

For details, see [Webhooks Overview](/docs/webhooks-overview).

## Architecture Complete

Your custody starter architecture is now set up.

| Component | Status |
| :-------- | :----- |
| Custody Wallet (Cold Storage) | Created with strict policies |
| Standby Wallet (Hot) | Created with admin approval policy |
| Deposit/Withdraw Wallet (Hot) | Created with no policies |
| Custody-Standby Whitelist | Configured |
| Standby-Deposit Whitelist | Configured |
| Receive Addresses | Ready to create for customers |

## Next Steps

- Share receive addresses with your customers.
- Set up [Webhooks](/docs/webhooks-overview) to monitor deposits.
- Configure [transaction monitoring](/docs/policies-overview) as needed.
- Review [Deposit Assets](/docs/deposit-assets) for deposit workflows.
- Review [Withdraw Overview](/docs/withdraw-overview) for withdrawal workflows.

## See Also

- [Custody Starter Architecture Overview](/docs/custody-starter-architecture-overview)
- [Create Addresses](/docs/wallets-create-addresses)
- [Consolidate Account Balance](/docs/wallets-consolidate)
- [Deposit Assets](/docs/deposit-assets)
