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

# Crypto deposits and withdrawals

> Fund end-client accounts with in-kind digital asset deposits, attribute them, and process withdrawals to trusted destinations.

## How it works

<Steps>
  <Step title="Create a deposit wallet">
    Create a subaccount-specific deposit wallet for the asset your client wants to deposit.
  </Step>

  <Step title="Share the address with your client">
    Share the deposit address, along with the blockchain and asset details.
  </Step>

  <Step title="Monitor and attribute the deposit">
    Detect the deposit via webhook or polling, then attribute it to the correct end client.
  </Step>

  <Step title="Add a trusted destination and withdraw">
    When your client wants to withdraw, register their external address as a trusted destination, then initiate the withdrawal.
  </Step>
</Steps>

***

## Fund accounts with digital assets

Steps must be completed in order — out-of-sequence execution risks funds being lost or returned.

### Deposit attribution

**Status values**

| `status`           | Details                                                                                                                  |
| :----------------- | :----------------------------------------------------------------------------------------------------------------------- |
| `PENDING`          | Deposit landed after Anchorage Digital auto-attribution attempt. Spam deposits marked by Anchorage will not appear here. |
| `INITIATED`        | Deposit detected; auto-attribution in progress. Moves to `PENDING` if auto-attribution fails.                            |
| `ATTRIBUTED`       | Terminal state — happy path.                                                                                             |
| `UNDER_REVIEW`     | Attributed but triggered a sanctions hit pending compliance clearance.                                                   |
| `BLOCKED`          | Confirmed true sanctions hit.                                                                                            |
| `NON_ATTRIBUTABLE` | Semi-terminal state for specific edge cases.                                                                             |

**Attribution type values**

| `attributionType` | Details                                                        |
| :---------------- | :------------------------------------------------------------- |
| `MANUAL_STAFF`    | Attributed by Anchorage Digital staff.                         |
| `MANUAL_CLIENT`   | Attributed by wealth manager via web dashboard.                |
| `CLIENT_API`      | Attributed by wealth manager via API key.                      |
| `AUTOMATIC`       | Attributed via travel rule message from originating VASP.      |
| `SPAM`            | Attributed as spam by Anchorage Digital or the wealth manager. |
| `TRUSTED_SOURCES` | Attributed automatically using a designated trusted source.    |

**Trusted sources**

Trusted sources auto-attribute recurring deposits from the same address. Create them in the Anchorage Digital web dashboard (API not available in production).

<Warning>
  Trusted sources should not be used if a single source address is shared by multiple end clients. Doing so may cause incorrect attribution and require the wealth manager to provide additional originator details to Anchorage Digital.
</Warning>

**Spam / unknown deposits**

Attribute dust or spam deposits as `SPAM` using **`POST /v2/deposit-attributions/{depositTransactionId}/spam`**. This prevents unwanted balances from appearing on the end client's account. Anchorage Digital will sweep these funds from on-chain wallets using the shared API key as needed.

**Automated attribution from VASPs**

Crypto deposits from VASPs over \$2,100 (the travel rule threshold) are automatically attributed if Anchorage Digital receives a travel rule message from an active TRUST network VASP. This is not instant — use the attribution API for faster fund access.

### Step 1: Get your `vaultId`

**`GET /v2/vaults`**

<CodeGroup>
  ```bash Request theme={null}
  curl --request GET \
       --url https://api.anchorage-staging.com/v2/vaults \
       --header 'Api-Access-Key: [API Key]' \
       --header 'accept: application/json'
  ```

  ```json Response theme={null}
  {
    "data": [
      {
        "accountName": "Wealth Manager - FBO Program Customers",
        "description": "",
        "name": "John Doe_Deposit wallet_Subaccount_123456789987654323456",
        "type": "VAULT",
        "vaultId": "7d04d1b820f1b5a903e47fd3019c58f3"
      }
    ]
  }
  ```
</CodeGroup>

### Step 2: Create a deposit wallet for the subaccount

**`POST /v2/vaults/{vaultId}/wallets`**

Create one wallet per subaccount per asset, specifying `subaccountId`. Create wallets on demand — when the customer requests a deposit address — rather than pre-creating wallets for every supported asset.

**Recommended naming convention:** `[PC name]_[Subaccount #]_Deposit Wallet`

<Note>
  Wallet creation is limited to 10 wallets per asset per 30 minutes. This limit will increase in coming months.
</Note>

<CodeGroup>
  ```bash Request theme={null}
  curl --request POST \
       --url https://api.anchorage-staging.com/v2/vaults/7d04d1b820f1b5a903e47fd3019c58f3/wallets \
       --header 'Api-Access-Key: [API Key]' \
       --header 'accept: application/json' \
       --header 'content-type: application/json' \
       --data '{
    "networkId": "BTC",
    "walletName": "John Doe_ec761b5e-fd2c-497a-a9a0-f8738ac97bdf_Bitcoin Deposit Wallet_1",
    "subaccountId": "ec761b5e-fd2c-497a-a9a0-f8738ac97bdf"
  }'
  ```

  ```json Response theme={null}
  {
    "data": {
      "depositAddress": {
        "address": "3KEFt8iLAGSHhKvQsVUabmAHZdWar45PnW",
        "addressId": "2be7ad5e4dccbdf2d82b77113d908e5cb",
        "addressSignaturePayload": "7b225465787441646472657373223a22334b45467438694c41475348684b765173565561626d41485a645761723435506f57227d",
        "signature": "dcb09503a0dfd592749f6298a59ea46aac549aa56a1127fa51efb1ad34663eabb55bab24c9c87ff7c0e09e6d9154daeadc1805e5cf297abd8a8b404bb6b7910b"
      },
      "isArchived": false,
      "isDefault": false,
      "networkId": "BTC",
      "subaccountId": "ec761b5e-fd2c-497a-a9a0-f8738ac97bdf",
      "vaultId": "7d04d1b820f1b5a903e47fd3019c58f3",
      "vaultName": "Advisor 1, FBO Program Customers",
      "walletId": "6aabaa5127f3757de379e724f69d6fa10",
      "walletName": "John Doe_ec761b5e-fd2c-497a-a9a0-f8738ac97bdf_Bitcoin Deposit Wallet_1"
    }
  }
  ```
</CodeGroup>

<Note>
  **Sandbox testnet assets:** `BTC_T` (BTC testnet), `ETHHOL` (ETH Holesky), `USDANCHOL` (USDC Holesky)
</Note>

Share the deposit address with the end client, along with the blockchain details (e.g., Ethereum mainnet vs. Base) and any deposit attribution requirements.

<Tip>
  For the first few deposits, have the end client send a small test amount to confirm the address and network are correct before transferring the full balance. Ensure both parties are aligned on the exact asset symbol and supported network — deposits to the wrong network may result in lost funds.
</Tip>

### Step 3: Identify a new deposit

Deposit confirmations are not immediate — they typically require 2 on-chain confirmations, which may take a few minutes.

**Option A:** Poll for pending attributions — **`GET /v2/deposit-attributions?status=PENDING`**

```json Response theme={null}
{
  "data": [
    {
      "assetType": "BTC",
      "depositTransactionId": "22a73be305a4131e2b3439ca5d0fbb7a",
      "status": "PENDING",
      "subaccountId": "cb80459c-a930-444e-8f17-69ba9d0e122f"
    }
  ]
}
```

**Option B:** Webhook notification — subscribe to `deposit.pending-attribution`:

```json Webhook payload theme={null}
{
  "payload": "eyJ0cmFuc2FjdGlvbklkIjoiNjE4Y2JkNTVlNzE2ZmFlMGVkODNjYTcyOWM4MDI2NmEifQ==",
  "timestamp": 1729112450,
  "message_id": "aa2dbc06-1665-44c0-bb8e-d2b0ad15a564",
  "event_type": "deposit.pending-attribution"
}
```

The `message_id` maps to the `depositTransactionId`.

<Warning>
  Ensure end clients only deposit supported assets. Deposits of unsupported assets into a wallet will result in lost funds.
</Warning>

### Step 4: Attribute the deposit

**`PATCH /v2/deposit-attributions/{depositTransactionId}`**

In production, collect AML deposit attribution data from the end client before sharing the deposit address — this enables automatic attribution once the deposit is detected.

`sourceWalletType` values:

| Value         | Description                                                                                  |
| :------------ | :------------------------------------------------------------------------------------------- |
| `CUSTODIAL`   | Third party holds the private key (e.g., Binance, Coinbase, Kraken, BitGo).                  |
| `SELF_HOSTED` | Owner holds the private key (e.g., MetaMask, Trust Wallet, Ledger, Trezor, Exodus, Phantom). |

<Warning>
  For spam/dust deposits, use **`POST /v2/deposit-attributions/{depositTransactionId}/spam`** instead to prevent unwanted balances from appearing on the account.
</Warning>

<CodeGroup>
  ```bash Request theme={null}
  curl --request PATCH \
       --url https://api.anchorage-staging.com/v2/deposit-attributions/aa2dbc06-1665-44c0-bb8e-d2b0ad15a564 \
       --header 'Api-Access-Key: [API Key]' \
       --header 'accept: application/json' \
       --header 'content-type: application/json' \
       --data '{
    "originatorName": "John Doe",
    "originatorCountry": "US",
    "sourceWalletType": "SELF_HOSTED",
    "notes": "US"
  }'
  ```

  ```json Response (attributed) theme={null}
  {
    "data": [
      {
        "assetType": "BTC",
        "attributedAt": "2024-04-09T19:31:02.046634Z",
        "attributionType": "CLIENT_API",
        "depositTransactionId": "aa2dbc06-1665-44c0-bb8e-d2b0ad15a564",
        "notes": "Example Attribution",
        "originatorCountry": "US",
        "originatorName": "John Doe",
        "sourceWalletType": "SELF_HOSTED",
        "status": "ATTRIBUTED",
        "subaccountId": "cb80459c-a930-444e-8f17-69ba9d0e122f"
      }
    ]
  }
  ```
</CodeGroup>

<Tip>
  After attributing in-kind deposits, [update the missing cost basis](/knowledge-base/platform/developers/wealth/wealth-management-tax#step-2-update-missing-cost-basis) via **`PATCH /v2/tax/transaction/{transactionId}`**.
</Tip>

### Step 5: View account balances

**`GET /v2/subaccounts/customers/{customerId}/accounts`**

<CodeGroup>
  ```bash Request theme={null}
  curl --request GET \
       --url https://api.anchorage-staging.com/v2/subaccounts/customers/{customerId}/accounts \
       --header 'Api-Access-Key: [API Key]' \
       --header 'accept: application/json'
  ```

  ```json Response theme={null}
  {
    "data": [
      {
        "subaccountId": "cb80459c-a930-444e-8f17-69ba9d0e122f",
        "name": "A1234_John Doe_Strat1",
        "customerId": "cf326d89b501d7ff2d1c7b7ffea4bd305a6561b54c9c6158160e17b5aca5cec2",
        "fees": [
          { "type": "MANAGEMENT", "rate": 0.01, "startDate": "2025-02-18", "isBillable": true },
          { "type": "CUSTODY", "rate": 0.01, "startDate": "2025-02-18", "isBillable": true }
        ],
        "balances": [
          { "assetType": "BTC", "totalBalance": "100", "availableForWithdrawal": "100", "availableForTrading": "100" },
          { "assetType": "USD", "totalBalance": "100000", "availableForWithdrawal": "100000", "availableForTrading": "100000" }
        ]
      }
    ]
  }
  ```
</CodeGroup>

***

## Withdraw digital assets

<Warning>
  **New programmatic in-kind withdrawals (released 2025-04-15).** Three key changes:

  1. New create trusted destinations API.
  2. New DocuSign approval required from the end client before creating the trusted destination.
  3. Updated withdrawal API payload for withdrawals to trusted destinations.
  4. API permission and key updates required.
</Warning>

### Step 1: Update API key permissions

Add the following two permissions to your API key permission group:

* **Withdrawal** — Yes
* **Manage trusted destinations** — Yes

Quorum approve the change before proceeding.

### Step 2: Add trusted destinations

Submit trusted destination requests via **`POST /v2/trusted_destinations`** for each end-client's external withdrawal address.

For wealth management integrations, trusted destinations are tied to an `owner` representing the end client (`customerId`).

**After submission:** A DocuSign is sent to the end client for each destination. Once signed, the Anchorage Digital ops team reviews and approves. If issues arise, Anchorage Digital will reach out.

```bash theme={null}
curl --request POST \
     --url https://api.anchorage-staging.com/v2/trusted_destinations \
     --header 'accept: application/json' \
     --header 'content-type: application/json' \
     --data '{
  "idempotentId": "YOUR_GENERATED_UUID_HERE",
  "trustedDestinations": [
    {
      "assetType": "ETH",
      "address": "0x430EF7FAB8e10dFb8B7c50c2026d0e247FEE4B8",
      "name": "Test Ethereum Address 3",
      "trustedDestinationAmlQuestionnaire": {
        "destinationType": "SELFHOSTED_WALLET",
        "selfhostedDescription": "Personal ETH wallet for testing",
        "selfhostedWalletOwner": "PERSON_OR_ENTITY",
        "recipientType": "PERSON",
        "recipientFirstName": "John",
        "recipientLastName": "Doe",
        "recipientFullName": "John Doe",
        "recipientCountry": "US",
        "recipientStreetAddress": "123 Main St",
        "recipientCity": "San Francisco",
        "recipientStateProvince": "CA",
        "recipientPostalCode": "94105"
      },
      "description": "Test Ethereum wallet for demo purposes",
      "memo": "ETH demo wallet 3",
      "isNetworkLevel": false
    }
  ],
  "owner": {
    "type": "CUSTOMER",
    "id": "7266559476aac38fc8c7c2022f93a9d1b9b618b1c9e2b4387840b595dcd374aa"
  }
}'
```

### Step 3: Initiate the withdrawal

Use **`POST /v2/transactions/withdrawal`**. Anchorage Digital account admins will need to verify on their iOS devices. Once quorum is complete, the operation proceeds through risk review, then broadcasts on-chain.

<Tip>
  Admins can batch approve multiple operations on iOS. See [Batched endorsements](/knowledge-base/platform/users/sending-assets#batched-endorsements).
</Tip>

<Note>
  Multiple withdrawals for the same asset queued simultaneously may be processed sequentially rather than in parallel. Flagged withdrawals may also delay same-asset withdrawals.
</Note>

```json Withdrawal request theme={null}
{
  "source": {
    "id": "15bb8b12-d991-45d2-b784-c83c4449265b",
    "type": "SUBACCOUNT"
  },
  "assetType": "ETH",
  "destination": {
    "id": "0xf0Ed16EeedD8111B40De252467eE9d0E14cbfe99",
    "type": "ADDRESS"
  },
  "amount": "1",
  "description": "",
  "withdrawalAmlQuestionnaire": {
    "useTrustedDestinationAml": true,
    "purpose": "INTRA_COMPANY"
  }
}
```

**`purpose` values:** `TRADING_SETTLEMENT`, `LENDING`, `INVESTMENT`, `EXPENSES`, `FEE_PAYMENT`, `GRANT_PAYMENT`, `PRIZE_AWARD`, `GIFT`, `REIMBURSEMENT`, `REBALANCE`, `INTRA_COMPANY`
