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

# How-to: Wire deposits and withdrawals

> Link bank accounts, deposit fiat, and withdraw stablecoins through wire transfers

Link your end customers' bank accounts to their Digital Asset Accounts so they
can move money between traditional banking and stablecoins. Fiat wire deposits
are automatically minted into the corresponding stablecoin, and wire withdrawals
redeem stablecoin balances and initiate a bank transfer.

## Prerequisites

Before you begin:

* Obtain an API key for Digital Asset Accounts from Circle.
* Have an onboarded and active account with an `accountId`.
* Install cURL on your development machine.

<Note>
  The Digital Asset Accounts API base URL is `https://api-sandbox.circle.com` for
  sandbox and `https://api.circle.com` for production. Set your API key in the
  `Authorization` header using the format `Bearer YOUR_API_KEY`. See
  [Sandbox environment](/digital-asset-accounts/references/testing-in-sandbox) and
  [Going to production](/digital-asset-accounts/references/going-to-production)
  for environment details.
</Note>

## Steps

### Step 1. Link a bank account

Link your end customer's bank account by providing the bank details and billing
information.

```shell theme={null}
curl --request POST \
  --url https://api-sandbox.circle.com/v1/accounts/banks/wires \
  --header 'Accept: application/json' \
  --header 'Authorization: Bearer ${YOUR_API_KEY}' \
  --header 'Content-Type: application/json' \
  --data '
{
  "accountId": "${ACCOUNT_ID}",
  "idempotencyKey": "${RANDOM_UUID}",
  "accountNumber": "123456789",
  "routingNumber": "021000021",
  "billingDetails": {
    "name": "Acme Corp",
    "line1": "100 Money Street",
    "city": "Boston",
    "district": "MA",
    "postalCode": "01234",
    "country": "US"
  },
  "bankAddress": {
    "bankName": "Chase Bank",
    "city": "New York",
    "country": "US",
    "line1": "270 Park Avenue",
    "district": "NY"
  }
}
'
```

**Response**

```json theme={null}
{
  "data": {
    "id": "b8a025e7-d5e5-4e5a-8e35-2f3a7d1c9b4a",
    "status": "complete",
    "description": "CHASE BANK ****6789",
    "trackingRef": "CIR3XXXYYY",
    "virtualAccountEnabled": false,
    "fingerprint": "abc123def456",
    "billingDetails": {
      "name": "Acme Corp",
      "line1": "100 Money Street",
      "city": "Boston",
      "postalCode": "01234",
      "district": "MA",
      "country": "US"
    },
    "bankAddress": {
      "bankName": "Chase Bank",
      "city": "New York",
      "country": "US"
    },
    "createDate": "2026-03-15T10:00:00Z",
    "updateDate": "2026-03-15T10:00:00Z"
  }
}
```

### Step 2. Get wire instructions

Retrieve the wire instructions for the linked bank account. Share these with
your end customer so they can send a wire deposit from their bank.

```shell theme={null}
curl --request GET \
  --url 'https://api-sandbox.circle.com/v1/accounts/banks/wires/${WIRE_ID}/instructions?accountId=${ACCOUNT_ID}' \
  --header 'Accept: application/json' \
  --header 'Authorization: Bearer ${YOUR_API_KEY}'
```

**Response**

```json theme={null}
{
  "data": {
    "trackingRef": "CIR3XXXYYY",
    "beneficiary": {
      "name": "Circle Internet Financial Inc",
      "address1": "99 High Street",
      "address2": "Boston, MA 02110"
    },
    "virtualAccountEnabled": false,
    "beneficiaryBank": {
      "name": "Silicon Valley Bank",
      "routingNumber": "121140399",
      "accountNumber": "1234567890",
      "currency": "USD",
      "country": "US"
    }
  }
}
```

The `trackingRef` is a unique reference code that identifies the wire deposit.
Your customer must include it in their wire transfer so Circle can match the
payment to the correct account.

<Warning>
  Your end customer must include the `trackingRef` when sending the wire transfer.
  Without this reference, the deposit cannot be matched to the correct account.
</Warning>

### Step 3. Deposit fiat (sandbox simulation)

In the sandbox environment, simulate a wire deposit using the mock payments
endpoint. In production, your end customer sends a real wire transfer using the
instructions from the previous step.

```shell theme={null}
curl --request POST \
  --url https://api-sandbox.circle.com/v1/mocks/payments/wire \
  --header 'Accept: application/json' \
  --header 'Authorization: Bearer ${YOUR_API_KEY}' \
  --header 'Content-Type: application/json' \
  --data '
{
  "trackingRef": "${TRACKING_REF}",
  "amount": {
    "amount": "10000.00",
    "currency": "USD"
  },
  "beneficiaryBank": {
    "accountNumber": "1234567890",
    "routingNumber": "121140399"
  }
}
'
```

**Response**

```json theme={null}
{
  "data": {
    "trackingRef": "CIR3XXXYYY",
    "beneficiaryBank": {
      "routingNumber": "121140399",
      "accountNumber": "1234567890"
    },
    "amount": {
      "amount": "10000.00",
      "currency": "USD"
    },
    "status": "pending"
  }
}
```

### Step 4. Check the balance

Confirm that the deposit has been credited to the account.

```shell theme={null}
curl --request GET \
  --url https://api-sandbox.circle.com/v1/accounts/balances/${ACCOUNT_ID} \
  --header 'Accept: application/json' \
  --header 'Authorization: Bearer ${YOUR_API_KEY}'
```

**Response**

```json theme={null}
{
  "data": {
    "available": [
      {
        "amount": "10000.00",
        "currency": "USD"
      }
    ],
    "unsettled": []
  }
}
```

### Step 5. Withdraw to a bank account

To withdraw stablecoins as fiat, create a withdrawal that specifies the amount,
the destination wire account, and the source account.

```shell theme={null}
curl --request POST \
  --url https://api-sandbox.circle.com/v1/accounts/withdrawals \
  --header 'Accept: application/json' \
  --header 'Authorization: Bearer ${YOUR_API_KEY}' \
  --header 'Content-Type: application/json' \
  --data '
{
  "idempotencyKey": "${RANDOM_UUID}",
  "destination": {
    "type": "wire",
    "id": "${WIRE_ID}"
  },
  "amount": {
    "amount": "5000.00",
    "currency": "USD"
  },
  "source": {
    "type": "account",
    "id": "${ACCOUNT_ID}"
  }
}
'
```

**Response**

```json theme={null}
{
  "data": {
    "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "sourceAccountId": "1017381855",
    "destination": {
      "type": "wire",
      "id": "b8a025e7-d5e5-4e5a-8e35-2f3a7d1c9b4a"
    },
    "amount": {
      "amount": "5000.00",
      "currency": "USD"
    },
    "toAmount": {
      "amount": "5000.00",
      "currency": "USD"
    },
    "status": "pending",
    "createDate": "2026-03-15T14:00:00Z",
    "updateDate": "2026-03-15T14:00:00Z"
  }
}
```

The withdrawal processes asynchronously. Monitor the status by polling the
withdrawals endpoint or by setting up
[webhook notifications](/api-reference/webhook-endpoints#v1-notifications).

If the source account has insufficient funds, the API returns an error:

```json theme={null}
{
  "code": 2,
  "message": "Insufficient funds. The source account does not have enough balance to complete this withdrawal."
}
```

Verify the account balance before initiating a withdrawal.

## List and retrieve wire accounts

You can query linked wire accounts at any time.

**List all wire accounts for an account**

```shell theme={null}
curl --request GET \
  --url 'https://api-sandbox.circle.com/v1/accounts/banks/wires?accountId=${ACCOUNT_ID}' \
  --header 'Accept: application/json' \
  --header 'Authorization: Bearer ${YOUR_API_KEY}'
```

**Get a specific wire account**

```shell theme={null}
curl --request GET \
  --url https://api-sandbox.circle.com/v1/accounts/banks/wires/${WIRE_ID} \
  --header 'Accept: application/json' \
  --header 'Authorization: Bearer ${YOUR_API_KEY}'
```
