Skip to main content

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.

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.
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 and Going to production for environment details.

Steps

Link your end customer’s bank account by providing the bank details and billing information.
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
{
  "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.
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
{
  "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.
Your end customer must include the trackingRef when sending the wire transfer. Without this reference, the deposit cannot be matched to the correct account.

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.
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
{
  "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.
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
{
  "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.
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
{
  "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. If the source account has insufficient funds, the API returns an error:
{
  "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
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
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}'