# Fund Go Accounts

Source: https://developers.bitgo.com/docs/crypto-as-a-service-fund-go-accounts

## Overview

Crypto-as-a-Service (CaaS) enables you and your clients to move fiat between bank accounts and Go Accounts. BitGo supports multiple fiat payments rails to accommodate different client preferences, use cases, and regulatory environments.

## Fiat Support

| Jurisdiction | Currency | Payment Rails |
| :------------------- | :-------------- | :---------------------------------------------------------------------------------------------------- |
| United States | USD | ACH debit, domestic and international wire transfers, CUBIX transfers, [Go Network](/docs/go-network-overview)  |
| Europe | EUR | SEPA Instant, SEPA, BLINC transfers, [Go Network](/docs/go-network-overview) |

## Prerequisites

* [Get Started](/docs/get-started-intro)
* [Create Go Accounts](/docs/crypto-as-a-service-go-accounts)

## Cookbooks

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

<Cookbook slug="caas-fund-go-account-fiat-curl" title="Fund Go Account with Fiat" />
<Cookbook slug="caas-fund-go-account-fiat-javascript" title="Fund Go Account with Fiat" />

<Cookbook slug="caas-fund-go-account-go-network" title="Fund Go Account (Go Network)" />

## Deposit Instructions

You can fetch your enterprise deposit instructions using the [Get deposit info](/reference/fiatgetdepositinfo) endpoint which returns the memo ID and available deposit bank accounts based on your enterprise jurisdiction. This information is useful when depositing with any of the payment rails we support. Some funding rails require memo ID and bank account details to match your deposit.

## BitGo-Approved Bank Accounts

Fiat withdrawals to bank accounts require the use of BitGo-approved bank accounts. You can use the [Add bank account](/reference/v2bankaccountadd) endpoint to add a bank account.

When you add a bank account to an enterprise it goes through a screening process. BitGo approves most bank accounts within 48 hours and they can use them for fiat operations immediately after approval. You can see the status of the bank account by calling the [Get bank account](/reference/v2bankaccountget) endpoint and checking the `verificationState` field.

### Approval Requirements

To ensure BitGo approves your bank account, verify the following requirements:

| Requirement | Description |
| :--- | :--- |
| **Valid Routing Number** | For US bank accounts, provide a valid 9-digit ABA routing number. BitGo validates routing numbers against the Federal Reserve directory. Invalid routing numbers result in rejection. |
| **Owner Name Match** | The `ownerName` must match the name of your end user. For example, if your enterprise is "John Doe", the bank account owner should be "John Doe". |
| **Account Type** | You must specify the `accountType` field as `checking` or `saving`. This field is required for both ACH and wire transactions to process correctly. |

### (Optional) Add Bank Account

>Endpoint: [Add bank account](/reference/v2bankaccountadd)

```shell cURL
export ACCESS_TOKEN="<SERVICE_USER_ACCESS_TOKEN>"
export ENTERPRISE_ID="<CHILD_ENTERPRISE_ID>"

# Note: 021000021 is a valid sample routing number (JPMorgan Chase Bank)
curl -X POST \
  https://app.bitgo-test.com/api/v2/bankaccounts \
  -H 'Content-Type: application/json' \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -d '{
    "type": "ach",
    "name": "JPMorgan Chase Bank",
    "accountNumber": "123456789012",
    "routingNumber": "021000021",
    "currency": "tfiatusd",
    "enterpriseId": "'"$ENTERPRISE_ID"'",
    "ownerName": "John Doe",
    "accountType": "checking",
    "description": "ACH deposits and withdrawals",
    "ownerAddressLine1": "123 Main Street",
    "ownerAddressLine2": "Suite 400",
    "ownerAddressCityLocality": "New York",
    "ownerAddressStateProvince": "NY",
    "ownerAddressPostalCode": "10001",
    "ownerAddressCountryCode": "US",
    "bankAddressLine1": "456 Financial Plaza",
    "bankAddressCityLocality": "New York",
    "bankAddressStateProvince": "NY",
    "bankAddressPostalCode": "10005",
    "bankAddressCountryCode": "US"
  }'
```
```js JavaScript
const BitGoJS = require('bitgo');

const bitgo = new BitGoJS.BitGo({
  accessToken: '<SERVICE_USER_ACCESS_TOKEN>',
  env: 'test',
});

// Note: 021000021 is a valid sample routing number (JPMorgan Chase Bank)
async function addBankAccount() {
  const bankAccount = await bitgo.post('/api/v2/bankaccounts').send({
    type: 'ach',
    name: 'JPMorgan Chase Bank',
    accountNumber: '123456789012',
    routingNumber: '021000021',
    currency: 'tfiatusd',
    enterpriseId: '<CHILD_ENTERPRISE_ID>',
    ownerName: 'John Doe',
    accountType: 'checking',
    description: 'ACH deposits and withdrawals',
    ownerAddressLine1: '123 Main Street',
    ownerAddressLine2: 'Suite 400',
    ownerAddressCityLocality: 'New York',
    ownerAddressStateProvince: 'NY',
    ownerAddressPostalCode: '10001',
    ownerAddressCountryCode: 'US',
    bankAddressLine1: '456 Financial Plaza',
    bankAddressCityLocality: 'New York',
    bankAddressStateProvince: 'NY',
    bankAddressPostalCode: '10005',
    bankAddressCountryCode: 'US',
  });

  console.log('Bank Account Added:', bankAccount);
  return bankAccount;
}

addBankAccount().catch(console.error);
```

### Step Result

The response includes the bank account details and the `verificationState` field indicating the current approval status.

```json JSON
{
  "id": "60749ab75f8c4500060f5a8b244dd0cb",
  "idHash": "c2f4cf5555a66d77",
  "currency": "tfiatusd",
  "token": "tusd",
  "name": "JPMorgan Chase Bank",
  "shortCountryCode": "US",
  "accountNumber": "****9012",
  "enterpriseId": "1032e75c451052000436831deb797af1",
  "ownerName": "John Doe",
  "verificationState": "pending",
  "createdAt": "2025-01-12T15:30:00.000Z",
  "type": "ach",
  "routingNumber": "021000021",
  "accountType": "checking",
  "description": "ACH deposits and withdrawals",
  "ownerAddressLine1": "123 Main Street",
  "ownerAddressLine2": "Suite 400",
  "ownerAddressCityLocality": "New York",
  "ownerAddressStateProvince": "NY",
  "ownerAddressPostalCode": "10001",
  "ownerAddressCountryCode": "US",
  "bankAddressLine1": "456 Financial Plaza",
  "bankAddressCityLocality": "New York",
  "bankAddressStateProvince": "NY",
  "bankAddressPostalCode": "10005",
  "bankAddressCountryCode": "US",
  "virtualDepositOnly": false,
  "fee": {
    "amount": "1600",
    "individualFees": [
      {
        "type": "static",
        "amount": "1600"
      }
    ]
  }
}
```

### Verification States

The endpoint returns one of the following verification states:

* `pending` - Bank account is under review. BitGo approves most accounts within 48 hours.
* `approved` - Bank account is ready for fiat operations.
* `rejected` - Bank account did not pass review. Review the requirements and resubmit.
* `revise` - Bank account requires corrections. Update the account and resubmit.
* `removed` - BitGo removed the bank account from the enterprise.

> 📘 **Note**
>
>  Use the [Get bank account](/reference/v2bankaccountget) endpoint to check the current verification status before initiating fiat operations.

## Steps

Select a funding rail to deposit or withdraw from your Go Accounts.

<Tabs>
<Tab title="ACH">
### ACH Deposits

ACH deposits enable USD transfers from BitGo-approved US bank accounts to Go Accounts and work well for B2B2C platforms where your users initiate funding through your frontend. ACH deposits work best for:

* Small-to-medium size deposits.
* User experiences that demand a “pull” model.
* Settlements that can wait 1–2 business days to settle.

> 🚧 **ACH Deposit Hold Period**
>
> When you deposit funds using ACH, BitGo places a 5 business day hold on your deposit. During this period, you can trade your deposited assets, but you can't withdraw or move the principal — this includes staking, transfers, or any other movement. You can withdraw any trading profits right away, but you must wait for the hold to expire before withdrawing your original deposit.

Before initiating ACH deposits, your platform must fund a reserve account that meets the following requirements:

* Minimum account balance: $25,000 if no deposit history.
* Standard account balance: 25% of the highest 2-day deposit volume in the previous month.
* You must replenish it within 5 business days if you withdraw funds.

In addition, to comply with Nacha rules, your ACH unauthorized returns must stay below 0.5% of total debits. If you exceed these thresholds, BitGo may suspend your ACH access.

> 🚧 **Plaid Integration Required**
>
> ACH deposits require bank accounts linked through Plaid. Your enterprise must have Plaid credentials configured by BitGo **before you can proceed**. Contact your Customer Success Manager (CSM) if you have not completed Plaid setup.

### 1. Set Up Reserve

ACH deposits take 1–2 business days to settle, while digital assets can transfer almost instantly. Therefore, BitGo requires you to pre-fund a fiat reserve to cover potential unauthorized return claims (fraud) from your end-users. You set up your reserve account using the Go Account in the parent enterprise - not the child enterprises.

#### 1.1 Designate Parent Enterprise

Contact your BitGo Customer Success Manager (CSM) to designate an enterprise in your organization your parent enterprise. Your CSM coordinates the set up and account configuration.

#### 1.2 Fund Reserve Account

Deposit a minimum of **$25,000** into the Go Account. This serves as your reserve account. ACH functionality isn't enabled until these funds fully settle. You can fund the Go Account using a wire transfer or a Go Network transfer.

#### 1.3 Maintain Reserve

As your ACH deposit volume grows, your reserve must grow with it. Each month:

1. Review your ACH deposit transaction history for the prior month.
2. Identify the peak 2-day volume — the 48-hour window with the highest total USD inflow. For example, if you processed $1M in deposits over a busy Monday and Tuesday, that $1M is your peak 2-day volume.
3. Calculate 25% of that peak amount. Using the example above, that's $250,000.
4. If 25% of your peak 2-day volume exceeds your current reserve balance, deposit the difference to bring the reserve up to the required level.

#### 1.4 Replenish Reserve

If the balance of your reserve account dips due to fraud or unauthorized returns, you must replenish it to the required level within 5 business days.

> 🚧 **Warning**
>
> If your deposit volume increases but you don't top up your reserve account to meet the 25% requirement, BitGo may suspend ACH access until you restore the reserve balance.

### 2. Get Transfer Limit

The transfer limit is the amount you can deposit using ACH per calendar day and resets every day at 12am EST.

>Endpoint: [Get Enterprise Transfer Limits](/reference/tradfiv1enterprisetransferlimits)

> 📘 **Note**
>
>  The test environment caps ACH deposits at $2,500/day and $10,000/week per enterprise. Use reasonable amounts and check remaining limits to avoid exceeding these thresholds during testing.

```shell cURL
export ENTERPRISE_ID="<YOUR_ENTERPRISE_ID>"
export ACCESS_TOKEN="<SERVICE_USER_ACCESS_TOKEN>"

curl -X GET \
  https://app.bitgo-test.com/api/tradfi/v1/enterprise-transfer-limits/$ENTERPRISE_ID/usd/ach-us/in \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -d '{
      "id": "01982d49-9f0d-7c50-847a-e04ea8a63165",
      "maximumTransferAllowed": "2500.00",
      "maximumTransferAllowedBase": 250000,
      "noLimit": false,
      "transferDirection": "in",
      "transferType": "ach-us"
}'
```

#### Step Result

```json JSON
{
  "id": "string",
  "maximumTransferAllowed": "string",
  "maximumTransferAllowedBase": 0,
  "noLimit": true,
  "transferDirection": "in",
  "transferType": "ach-us"
}
```

### 3. Create Plaid Link Token

Create Plaid Link token for the enterprise. Use this token to initialize the Plaid Link widget in your application.
If your application runs on a mobile device, include the `androidPackageName` or `redirectUri` parameters to support OAuth redirect flows.

> Endpoint: [Create Plaid Link token](/reference/tradfiv1plaidlinktokencreate)

```shell
export ENTERPRISE_ID="<YOUR_ENTERPRISE_ID>"
export ACCESS_TOKEN="<SERVICE_USER_ACCESS_TOKEN>"
export ANDROID_PACKAGE_NAME="<YOUR_ANDROID_PACKAGE_NAME>" # Required for Android OAuth flows
export REDIRECT_URI="<YOUR_REDIRECT_URI>" # Required for mobile and web OAuth flows

curl -X POST https://app.bitgo-test.com/api/tradfi/v1/plaid/link/token \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "enterpriseId": "'"$ENTERPRISE_ID"'",
    "androidPackageName": "'"$ANDROID_PACKAGE_NAME"'", # Required for Android OAuth flows
    "redirectUri": "'"$REDIRECT_URI"'" # Required for mobile and web OAuth flows
  }'
```

> 📘 **Note**
>
>  If you haven't configured your Plaid credentials, the server responds with `428 Precondition Required`. Contact your BitGo Customer Success Manager (CSM) to get your Plaid credentials set up.

Use the returned link token to render the Plaid Link widget in your application. Refer to the official Plaid documentation for rendering guidance, but use the BitGo APIs (described in this guide) for creating and exchanging tokens.

| Platform | Plaid Documentation |
|---|---|
| Web | [Plaid Link for Web](https://plaid.com/docs/link/web/) |
| iOS | [Plaid Link for iOS](https://plaid.com/docs/link/ios/) |
| Android | [Plaid Link for Android](https://plaid.com/docs/link/android/) |
| React Native | [Plaid Link for React Native](https://plaid.com/docs/link/react-native/) |

---

### 4. Exchange the Plaid Public Token

Once you finish selecting the bank accounts in the Plaid widget, Plaid returns a public token to your application. Exchange this token with BitGo to complete the bank account linking process.

> Endpoint: [Exchange Plaid Public Token](/reference/tradfiv1plaidlinktokenexchange)

```shell
export ENTERPRISE_ID="<YOUR_ENTERPRISE_ID>"
export LINK_TOKEN="<LINK_TOKEN_FROM_STEP_1>"
export PUBLIC_TOKEN="<PUBLIC_TOKEN_FROM_PLAID>"
export ACCESS_TOKEN="<ACCESS_TOKEN>"
export IP_ADDRESS="<IP_ADDRESS>"

curl -X POST https://app.bitgo-test.com/api/tradfi/v1/plaid/link/token/exchange \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "enterpriseId": "'"$ENTERPRISE_ID"'",
    "linkToken": "'"$LINK_TOKEN"'",
    "publicToken": "'"$PUBLIC_TOKEN"'",
    "ipAddress": "'"$IP_ADDRESS"'" # IP address of the end user who completed Plaid Link. Optional, but provide this value to improve the users Instant Credit trust score.
  }'
```

BitGo fetches the bank accounts selected by the user asynchronously. BitGo adds them to the user's account within a few seconds.

### 5. Get Bank Account

Retrieve the linked bank account to obtain the `bankAccountId` needed to initiate the ACH deposit. You can list all bank accounts or get a specific one by ID.

> Endpoint: [Get Deposit Info](/reference/fiatgetdepositinfo)

```shell
export BANK_ACCOUNT_ID="<BANK_ACCOUNT_ID>"
export ACCESS_TOKEN="<ACCESS_TOKEN>"

curl -X GET \
  https://app.bitgo-test.com/api/v2/bankaccounts/deposit/info?currency=fiatusd \
  -H "Authorization: Bearer $ACCESS_TOKEN"
```

#### Step Result

```json JSON
{
  "memoId": "string",
  "bankAccounts": [
    {
      "type": "ach",
      "routingNumber": "string",
      "accountType": "checking", 
      "id": "string", // Bank account id used for the next step,
      "description": "Nickname for Bank Acount", // User-provided description of the account.
      "name": "Bank Name"
    }
  ]
}
```

### 6. Create Bank Transfer

Initiate a new bank transfer using the `walletId` and `bankAccountId` as counterparties. The system infers most details from the `bankAccountId`. The same `enterpriseId` must own both the `walletId` and `bankAccountId`.

>Endpoint: [Create a Bank Transfer](/reference/tradfiv1bank-transferscreate)

```shell cURL
export ACCESS_TOKEN="<SERVICE_USER_ACCESS_TOKEN>"
export AMOUNT="<AMOUNT_TO_DEPOSIT>"
export BANK_ACCOUNT_ID="<BANK_ACCOUNT_ID>" # ID from previous step. 
export WALLET_ID="<WALLET_ID>"

curl -X POST https://app.bitgo-test.com/api/tradfi/v1/bank-transfers \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": "'"$AMOUNT_TO_DEPOSIT"'",
    "bankAccountId": "'"$BANK_ACCOUNT_ID"'",
    "transferDirection": "in",
    "walletId": "'"$WALLET_ID"'"
  }'
  ```

#### Step Result

```json JSON
{
  "amount": "string",
  "applyInstantCredit": true,
  "bankAccountId": "string",
  "createdAt": "2026-04-09T17:17:30.615Z",
  "enterpriseId": "string",
  "estimatedEffectiveOn": "2026-04-09",
  "id": "string",
  "instantCreditLiability": true,
  "memoId": "string",
  "settledAt": "2026-04-09T17:17:30.615Z",
  "status": "initiated",
  "transferDirection": "in",
  "transferType": "ach-us",
  "txid": "string",
  "walletId": "string"
}
```

### 7. Get Bank Transfer

Use this call to check the transfer status, settlement timestamps, and other details.

> 📘 **Note**
>
> This endpoint is only available in the test environment.

>Endpoint: [Get Bank Transfer](/reference/tradfiv1bank-transfersget)

```shell cURL
export ACCESS_TOKEN="<SERVICE_USER_ACCESS_TOKEN>"
export TRANSACTION_ID="<TX_ID>"

curl -X GET https://app.bitgo-test.com/api/tradfi/v1/bank-transfers/$TX_ID \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Accept: application/json" \
  ```

#### Step Result

```json JSON
{
  "amount": "string",
  "applyInstantCredit": true,
  "bankAccountId": "string",
  "createdAt": "2026-04-10T15:31:57.502Z",
  "enterpriseId": "string",
  "estimatedEffectiveOn": "2026-04-10",
  "id": "string",
  "instantCreditLiability": true,
  "memoId": "string",
  "settledAt": "2026-04-10T15:31:57.502Z",
  "status": "initiated",
  "transferDirection": "in",
  "transferType": "ach-us",
  "txid": "string",
  "walletId": "string"
}
```

The API automatically enforces daily transfer limits. If the deposit would exceed the allowed amount, the request returns an error. You can check remaining limits at any time using the [List Enterprise Transfer Limits](https://developers.bitgo.com/reference/tradfiv1enterprisetransferlimits) endpoint.

ACH deposits typically settle within 1–2 business days.

---

### Instant Credit (Optional)

Instant Credit allows your users to receive funds in their Go Account immediately after initiating an ACH deposit, rather than waiting for settlement.

#### How It Works

1. When an account initiates a deposit with Instant Credit enabled, BitGo performs a risk analysis using data from the linked Plaid account (such as the current bank balance).
2. The risk provider returns a timeline assessment — either **T+1** (low risk, advances credit) or **T+4** (higher risk, does not advance credit).
3. If approved, the Go Account ledger credits immediately and the funds become spendable, even though ACH settlement is still pending.
4. Once the ACH transfer fully settles, the instant credit transaction reconciles automatically.

#### Requirements

For Instant Credit to be applied, all of the following must be true:

- The enterprise integrates with Plaid.
- The reserve account holds enough funds to cover instant credit above the minimum threshold.
- The deposit request sets the `applyInstantCredit` flag to `true`.
- The indexed ledger allows Instant Credit.
- The transfer type and direction qualify for instant credit (currently ACH pulls only).
- The enterprise (and optionally the wallet) meets the risk criteria.

#### Monitoring Instant Credit Liability

Transfers with active Instant Credit count against your reserve account balance. You can check the `instantCreditLiability` field on individual transfers to determine how much of your reserve is currently committed.

> 📘 **Important**
>
>  Instant Credit is not guaranteed. If the risk analysis returns an unfavorable result, the deposit proceeds normally with standard settlement timing.

</Tab>
<Tab title="Wire">
### Wire Deposits

Wire transfer deposits are a reliable way to fund Go Accounts with high-value or international deposits. BitGo provides deposit instructions specific to each enterprise and Go Account. Wire transfers work best for:

* Large-value deposits.
* Time-sensitive transfers.
* International fiat inflows.

### 1. Get Deposit Details

Get bank account details for BitGo and a memo ID. All wire transfers must include a memo ID. This ID links your deposit to your account.

```shell cURL
export ACCESS_TOKEN="YOUR_ACCESS_TOKEN"
export GO_ACCOUNT_ID="GO_ACCOUNT_ID"
export CURRENCY="tfiatusd" # The BitGo-supported fiat currency you want to deposit

curl -X GET \
  "https://app.bitgo-test.com/api/v2/bankaccounts/deposit/info?goAccountId=$GO_ACCOUNT_ID&currency=$CURRENCY" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $ACCESS_TOKEN"
```
```js JavaScript
export type Fee {
  amount: string
  individualFees:
    {
        type: "static" | "variable",
        amount: string
    }[]
}

export type BankAccount {
  id: string;
  description?: string;
  idHash: string;
  currency: string;
  accountNumber: string;
  token: string;
  name: string;
  shortCountryCode: string;
  enterpriseId: string;
  trustOrg: string;
  ownerName: string;
  verificationState: string;
  createdAt: string;
  ownerAddressLine1: string;
  ownerAddressLine2?: string;
  ownerAddressCityLocality?: string;
  ownerAddressStateProvince?: string;
  ownerAddressPostalCode?: string;
  ownerAddressCountryCode: string;
  bankAddressLine1: string;
  bankAddressLine2?: string;
  bankAddressCityLocality?: string;
  bankAddressStateProvince?: string;
  bankAddressPostalCode?: string;
  bankAddressCountryCode: string;
  virtualDepositOnly: boolean;
  type: string;
  routingNumber?: string;
  swiftCode?: string;
  accountType: string;
  fee: Fee
}

export type DepositInfo = {
  memoId: string;
  bankAccounts: BankAccount[];
};
```

#### Step Result

```json JSON
{
    "memoId": "JVAIBEMHXT",
    "bankAccounts": [
        {
            "id": "64ae84bdb25d190007958872b5104a7f",
            "idHash": "cd303c82c4c74abf",
            "currency": "tfiatusd",
            "accountNumber": "5766400",
            "token": "tusd",
            "name": "Customers Bank ",
            "shortCountryCode": "US",
            "enterpriseId": "5bd795f1bf7435a503a0a647ec5d3b3d",
            "trustOrg": "BitGo Trust",
            "ownerName": "BitGo Trust Company, Inc",
            "verificationState": "approved",
            "createdAt": "2024-03-07T17:10:57.146Z",
            "ownerAddressLine1": "6216 S Pinnacle Pl Ste #101",
            "ownerAddressCityLocality": "Sioux Falls",
            "ownerAddressStateProvince": "SD",
            "ownerAddressPostalCode": "57108",
            "ownerAddressCountryCode": "US",
            "bankAddressLine1": "40 General Blvd Suite #200",
            "bankAddressCityLocality": "Malvern",
            "bankAddressStateProvince": "PA",
            "bankAddressPostalCode": "19355",
            "bankAddressCountryCode": "US",
            "virtualDepositOnly": false,
            "type": "wire",
            "routingNumber": "031302971",
            "accountType": "unknown",
            "fee": {
                "amount": "1600",
                "individualFees": [
                    {
                        "type": "static",
                        "amount": "1600"
                    }
                ]
            },
        },
    ]
}
```

### 2. Deposit Fiat Currency

Depositing fiat currency from your bank account requires using your bank app or API to initiate a wire or an ACH deposit. Review your bank documentation or contact them to learn more.

> 📘 **Note**
>
> Ensure to include the memo ID in order to prevent delays in accrediting deposits to your Go Account.

#### Step Result

The balance of fiat currency in your Go Account updates with the deposited amount. The deposited balance is immediately available for trades.

You can verify successful deposits with the [Get Account Balance](/reference/tradeaccountsbalances) endpoint.

### 1. Get `idHash`

>Endpoint: [List Bank Accounts](/reference/v2bankaccountlist)

```shell cURL
export ENTERPRISE_ID="<ENTERPRISE_ID>"
export ACCESS_TOKEN="<SERVICE_USER_ACCESS_TOKEN>"

curl -X GET \
  https://app.bitgo-test.com/api/v2/bankaccounts?enterpriseId=$ENTERPRISE_ID \
  -H 'Content-Type: application/json' \
  -H "Authorization: Bearer $ACCESS_TOKEN"
```

#### Step Result

BitGo identifies your bank account with a unique `idHash` that you can pass as the `address` value in the next step. You also receive information about the available payment rails and associated bank fees.

```json JSON
{
    "bankAccounts": [
        {
            "type": "wire", // available payment rails vary by bank and region
            "accountNumber": "012345678",
            "address1": "test",
            "address2": "test",
            "enterpriseId": "1032e75c451052000436831deb797af1",
            "id": "60749ab75f8c4500060f5a8b244dd0cb",
            "name": "My Bank",
            "owner": {
                "name": "test",
                "address1": "test",
                "address2": "test"
            },
            "idHash": "c2f4cf5555a66d77",
            "routingNumber": "087654321",
            "shortCountryCode": "US",
            "verificationState": "approved",
            "fee": { // fees vary by payment rail and bank
              "amount": "string",
              "individualFees": [
                {
                  "type": "static",
                  "amount": "string"
                }
              ]
            },
            "feeInfo": {
              "coin": "fiatusd",
              "bank": "silvergate",
              "type": "static",
              "amount": "string"
            },
        }
    ]
}
```

### 2. Build Transaction

To withdraw assets from your Go Account to a bank account, you must build a transaction and send the assets, on chain.

>Endpoint: [Build a Transaction](/reference/v2wallettxbuild)

```shell cURL
export COIN="<ASSET_ID>" # Asset IDs in Go Accounts always start with "ofc" (such as ofctbtc4)
export WALLET_ID="<YOUR_WALLET_ID>"
export ACCESS_TOKEN="<SERVICE_USER_ACCESS_TOKEN>"
export AMOUNT="<AMOUNT_IN_BASE_UNITS>"
export ADDRESS="<DESTINATION_ADDRESS_OR_ID_HASH>" # If withdrawing fiat to a bank account, use the `idHash`, returned in the prior step

curl -X POST \
  https://app.bitgo-test.com/api/v2/$COIN/wallet/$WALLET_ID/tx/build \
  -H 'Content-Type: application/json' \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -d '{
    "recipients": [
      {
        "amount": "'"$AMOUNT"'",
        "address": "'"$ADDRESS"'"
      }
    ]
}'
```
```js JavaScript
let params = {
  recipients: [
    {
      amount: 1000,
      address: '2NFfxvXpAWjKng7enFougtvtxxCJ2hQEMo4',
      // Use address when sending to a wallet on chain
      walletId: '654ec786c07fe6dc0dcfe03916ec4bb0',
      // Use walletId when sending to another Go Account off chain
    },
  ],
};
wallet.prebuildTransaction(params).then(function (transaction) {
  // print transaction details
  console.dir(transaction);
});
```

#### Step Result

```json JSON
{
  "payload": "{\"coin\":\"ofctbtc4\",\"recipients\":[{\"address\":\"tb1q5mwcr2749nnm5c5d6rzx5h92l2u9ex5jzygzd39vfv9qerj5fmjqwlgy4t\",\"amount\":\"1\"}],\"fromAccount\":\"62c5b1de8a0c5200071c9a603bdbadc5\",\"nonce\":\"d8e5d930-f827-42b1-ad85-40544dad1be6\",\"timestamp\":\"2025-06-25T17:45:56.394Z\",\"feeString\":\"0\",\"shortCircuitBlockchainTransfer\":false,\"isIntraJXTransfer\":false}",
  "feeInfo": { "feeString": "0" },
  "coin": "ofc",
  "token": "ofctbtc4"
}
```

### 3. Authenticate Transaction

Use your Go Account passphrase to authenticate the transaction. To ensure your passphrase does not travel over the Internet, you must use BitGo Express in external-signing mode or the JavaScript SDK. If you're using Express in external signing-mode, configure your Go Account passphrase as the `WALLET_<walletId>_PASSPHRASE` environment variable.

```shell cURL (External Signing-Mode)
export BITGO_EXPRESS_HOST="<YOUR_LOCAL_HOST>"
export ACCESS_TOKEN="<SERVICE_USER_ACCESS_TOKEN>"
export WALLET_ID="<YOUR_WALLET_ID>"
export WALLET_PASSPHRASE="<YOUR_GO_ACCOUNT_PASSPHRASE>"

curl -X POST \
  http://$BITGO_EXPRESS_HOST/api/v2/ofc/signPayload \
  -H 'Content-Type: application/json' \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -d '{
   "walletId": "'"$WALLET_ID"'",
   "walletPassphrase": "'"$WALLET_PASSPHRASE"'",
   "payload": "{\"coin\":\"ofctbtc4\",\"recipients\":[{\"address\":\"tb1q5mwcr2749nnm5c5d6rzx5h92l2u9ex5jzygzd39vfv9qerj5fmjqwlgy4t\",\"amount\":\"190000\"}],\"fromAccount\":\"67ab85b5190bf872e84da2b6e527d9f3\",\"nonce\":\"77d91a11-a7fa-4ad7-91e5-f054328717f9\",\"timestamp\":\"2025-06-26T15:02:06.924Z\",\"feeString\":\"0\",\"shortCircuitBlockchainTransfer\":false,\"isIntraJXTransfer\":false}"
}
```
```js JavaScript
// assuming that "bitgo" is an already initialized bitgo instance
  const wallet = await bitgo.coin('ofc').wallets().get({ id: goAccountId });

  if (wallet === undefined) {
    throw new Error(`Could not find OFC wallet ${goAccountId}`);
  }

  const walletPassphrase = "<YOUR_WALLET_PASSPHRASE>";
  const tradingAccount = wallet.toTradingAccount();
  const stringifiedPayload = JSON.stringify(<payload_returned_by_tx/build_api>);
  const signature = await tradingAccount.signPayload({
    payload: stringifiedPayload,
    walletPassphrase,
  });
```

#### Step Result

```json JSON
{
  "coin": "ofctbtc4",
  "recipients": [
    {
      "address": "tb1q5mwcr2749nnm5c5d6rzx5h92l2u9ex5jzygzd39vfv9qerj5fmjqwlgy4t",
      "amount": "1"
    }
  ],
  "fromAccount": "62c5b1de8a0c5200071c9a603bdbadc5",
  "nonce": "77d91a11-a7fa-4ad7-91e5-f054328717f9",
  "timestamp": "2025-06-26T15:02:06.924Z",
  "feeString": "0",
  "shortCircuitBlockchainTransfer": false,
  "isIntraJXTransfer": false,
  "payload": "{\"coin\":\"ofctbtc4\",\"recipients\":[{\"address\":\"tb1q5mwcr2749nnm5c5d6rzx5h92l2u9ex5jzygzd39vfv9qerj5fmjqwlgy4t\",\"amount\":\"1\"}],\"fromAccount\":\"62c5b1de8a0c5200071c9a603bdbadc5\",\"nonce\":\"77d91a11-a7fa-4ad7-91e5-f054328717f9\",\"timestamp\":\"2025-06-26T15:02:06.924Z\",\"feeString\":\"0\",\"shortCircuitBlockchainTransfer\":false,\"isIntraJXTransfer\":false}",
  "signature": "20dda1e9558adb297f69020f94cbf4955fabec73478506347dbb5ac8e73b506fc908bbc48bde75b339b99f5de808ed34b2017055c9df198fd1f8b4e524899f9583"
}
```

### 4. Send Transaction

The following example withdraws fiat to a bank account. However, you can also withdraw fiat to another Go Account, if the recipient address appears on the allowlist.

>Endpoint: [Send Half-Signed Transaction](/reference/v2wallettxsend)

```shell cURL (Fiat to Bank Account)
export WALLET_ID="<YOUR_WALLET_ID>"
export ACCESS_TOKEN="<SERVICE_USER_ACCESS_TOKEN>"
export ADDRESS="<ID_HASH>"
export AMOUNT="<AMOUNT_IN_BASE_UNITS>"

curl -X POST \
  https://app.bitgo-test.com/api/v2/ofctusd/wallet/$WALLET_ID/tx/send \
  -H 'Content-Type: application/json' \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -d '{
    "recipients": [
      {
        "address": "'"$ADDRESS"'",
        "amount": "'"$AMOUNT"'"
      }
    ],
    "halfSigned": {
      "payload": {
        "coin": "ofctusd",
        "recipients": [
          {
            "address": "'"$ADDRESS"'",
            "amount": "'"$AMOUNT"'"
          }
        ],
        "fromAccount": "<wallet id>",
        "nonce": "f4af25d0-a037-4afc-8ce6-d7f158d826d1",
        "timestamp": "2021-09-10T22:45:20.777Z",
        "idfSignedTimestamp": "2021-09-10T22:45:20.113Z",
        "idfVersion": 1,
        "idfUserId": "<user id>",
        "feeString": "1000"
      },
      "signature": "<signature>"
    }
  }'
```

#### Step Result

```json JSON (Fiat to Bank Account)
{
    "transfer": {
        "id": "<id>",
        "coin": "ofctusd",
        "wallet": "<wallet id>",
        "walletType": "trading",
        "enterprise": "603ca88c44f82002560378421dc7a191",
        "txid": "ddd6875812fa59f899a68059ff303bfa6d39fc350ee687c407383d0444b43d2b",
        "height": 999999999,
        "heightId": "999999999-613be001f3de560006842d52251d5d49",
        "date": "2021-09-10T22:45:21.342Z",
        "type": "send",
        "value": -10000,
        "valueString": "-10000",
        "baseValue": -10000,
        "baseValueString": "-10000",
        "feeString": "0",
        "payGoFee": 0,
        "payGoFeeString": "0",
        "usd": -100,
        "usdRate": 1,
        "state": "signed",
        "instant": false,
        "isReward": false,
        "isFee": false,
        "tags": [
            "603ca8c01b83cb000656311787dab4cd",
            "603ca88c44f82002560378421dc7a191"
        ],
        "history": [
            {
                "date": "2021-09-10T22:45:21.340Z",
                "action": "signed"
            },
            {
                "date": "2021-09-10T22:45:21.216Z",
                "user": "5e4ed695ae2e542100336fb16e586019",
                "action": "created"
            }
        ],
        "signedDate": "2021-09-10T22:45:21.340Z",
        "entries": [
            {
                "address": "address",
                "wallet": "603ca8c01b83cb000656311787dab4cd",
                "value": -10000,
                "valueString": "-10000"
            },
            {
                "address": "bf6cc5252438dc85",
                "value": 10000,
                "valueString": "10000"
            }
        ],
        "signedTime": "2021-09-10T22:45:21.340Z",
        "createdTime": "2021-09-10T22:45:21.216Z"
    },
    "txid": "ddd6875812fa59f899a68059ff303bfa6d39fc350ee687c407383d0444b43d2b",
    "tx": {
    "transaction": {
      "coin": "ofctusd",
      "recipients": [
        {
          "address": "<bank id hash>",
          "amount": "10000"
        }
      ],
      "fromAccount": "<wallet id>",
      "nonce": "f4af25d0-a037-4afc-8ce6-d7f158d826d1",
      "timestamp": "2021-09-10T22:45:20.777Z",
      "idfSignedTimestamp": "2021-09-10T22:45:20.113Z",
      "idfVersion": 1,
      "idfUserId": "<user id>",
      "feeString": "0"
    },
    "signature": "<signature>",
    "idfVersion": 1,
    "idfSignedTimestamp": "2021-09-10T22:45:20.113Z",
    "idfUserId": "<user id>"
  },
    "status": "signed"
}
```

### 5. Approve Transaction (Optional)

>Endpoint: [Update Pending Approval](/reference/v2approvalupdate)

```shell cURL
export COIN="<ASSET_ID>"
export APPROVAL_ID="<APPROVAL_ID>"
export ACCESS_TOKEN="<SERVICE_USER_ACCESS_TOKEN>"
export OTP="<OTP>"

curl -X POST \
  http://api/v2/$COIN/pendingapprovals/$APPROVAL_ID
  -H 'Content-Type: application/json' \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -d '{
    "state": "approved",
    "otp": "'"$OTP"'"
}'
```
```js JavaScript
const baseCoin = this.bitgoSDK.coin(initialPendingApproval.coin);
const pendingApproval = await baseCoin.pendingApprovals().get({ id: initialPendingApproval.id });
const result = await pendingApproval.approve(params);
```

#### Step Result

Once approved, BitGo rebuilds the unsigned transaction, applying the most up-to-date fees.

```json JSON
{
  "id": "655686880765186f0b3e9e88e1bdd0f4",
  "coin": "tbtc4",
  "wallet": "6553e933288be490293ae748efafeaaf",
  "enterprise": "62c5ae8174ac860007aff138a2d74df7",
  "creator": "62ab90e06dfda30007974f0a52a12995",
  "createDate": "2023-11-16T21:15:52.703Z",
  "info": {
    "type": "transactionRequest",
    "transactionRequest": {
      "requestedAmount": "10000",
      "fee": 45242,
      "sourceWallet": "6553e933288be490293ae748efafeaaf",
      "policyUniqueId": "6553e933288be490293ae753",
      "recipients": [
        {
          "address": "2N3sBpM1RnWRMXnEVoUWnM7xtYzL756JE2Q",
          "amount": "10000",
          "_id": "655686880765186f0b3e9e8a"
        }
      ],
      "buildParams": {
        "recipients": [
          {
            "address": "2N3sBpM1RnWRMXnEVoUWnM7xtYzL756JE2Q",
            "amount": "10000"
          }
        ]
      },
      "coinSpecific": {
        "tbtc4": {
          "txHex": "01000000000101eac5e7d68acfc2349672fb99094e79c2006e5fd663475c8f1eb6f29095970b740100000000ffffffff02102700000000000017a914747e6b7f5db53794b0fc01d95878e0f9b6db96738746c1020000000000220020efb9deaabeab5d62cecc363f24cd6deafcdd14d93d8734f7f01ed3953e732a640500483045022100cd6c221e4cefbb51aa82087d86e7d089b2473eb21ae809dba89eb9f13c4caf19022000f3b7f1b7fec2dc49cbfce35baa69ca37ab9ee8e51c779cde5b98a653f3e142010000695221029bde55661e4f359cf9ca2d1846c235e752f760ed6d65e2018f821253e78b3c722103f2b4a813ab79e4fb46edf3a6a87fb154a85b45810158e949f41a3fce3c9bf574210399a6d766f6d3a3843f8479446ee766b5745dc15c24d1db5149214d27987bd29453ae00000000"
        }
      },
      "validTransaction": "01000000000101eac5e7d68acfc2349672fb99094e79c2006e5fd663475c8f1eb6f29095970b740100000000ffffffff02102700000000000017a914747e6b7f5db53794b0fc01d95878e0f9b6db96738746c1020000000000220020efb9deaabeab5d62cecc363f24cd6deafcdd14d93d8734f7f01ed3953e732a640400483045022100cd6c221e4cefbb51aa82087d86e7d089b2473eb21ae809dba89eb9f13c4caf19022000f3b7f1b7fec2dc49cbfce35baa69ca37ab9ee8e51c779cde5b98a653f3e14201473044022002b246c43722fec49858caf6b0605a0d01a6b6c13c964b84bf272604fd3951780220324ee44ba3ce8febb154c317e688a5f6ed410ad8e2bd77c5678bf1f7f3eb45f601695221029bde55661e4f359cf9ca2d1846c235e752f760ed6d65e2018f821253e78b3c722103f2b4a813ab79e4fb46edf3a6a87fb154a85b45810158e949f41a3fce3c9bf574210399a6d766f6d3a3843f8479446ee766b5745dc15c24d1db5149214d27987bd29453ae00000000",
      "validTransactionHash": "ff40ccd5c8ba75ffdce27d8584b6e8ee625cb3f71f7cbb6d072a445a97c2c8c3"
    }
  },
  "state": "approved",
  "scope": "wallet",
  "userIds": [
    "62ab90e06dfda30007974f0a52a12995",
    "627ff9325a5c1b0007c05a40d15e1522"
  ],
  "approvalsRequired": 1,
  "singleRunResults": [
    {
      "ruleId": "Custody Enterprise Transaction ID Verification",
      "triggered": false,
      "_id": "655686880765186f0b3e9e89"
    }
  ],
  "resolvers": [
    {
      "user": "627ff9325a5c1b0007c05a40d15e1522",
      "date": "2023-11-16T21:33:24.644Z",
      "resolutionType": "pending"
    }
  ]
}
```
</Tab>
<Tab title="Go Network">
### Go Network Transfers

You can instantly transfer fiat between Go Accounts over Go Network. BitGo manages the off-chain ledger and updates Go Account balances accordingly. Fiat transfers over the Go Network are ideal for moving liquidity between child enterprises or white-labeled partners. Go Network transfers are best for:

* Real-time enterprise-to-enterprise settlements.
* Treasury operations between sub-accounts.
* Transfers across platforms integrated with BitGo.

### 1. Create a Connection

Before you can create a settlement with a new counterparty, you need a Go Account connection. Connections exist between two Go Accounts (not between enterprise IDs) and are one-way. For example, if Go Account A creates a connection to Go Account B, the connection is from A → B, and only Go Account A can initiate settlements using that connection. This connection includes the `addressBookConnectionId` and `addressBookConnectionUpdatedAt` values that you pass in the settlement request.

### 1.1 List Your Enterprise

List your enterprise in the public directory so that other enterprises can find you and add you as a counterparty.

>Endpoint: [Create Enterprise Listing](/reference/v1postlistingroute)

```shell cURL
export ACCESS_TOKEN="<SERVICE_USER_ACCESS_TOKEN>"
export DESCRIPTION="<YOUR_PUBLIC_DESCRIPTION>"

curl -X POST \
  https://app.bitgo-test.com/api/address-book/v1/listing/global \
  -H 'Content-Type: application/json' \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -d '{"description": "'"$DESCRIPTION"'"}'
```

#### Step Result

Your enterprise is now discoverable in the public directory.

```json JSON
{
    "id": "9f627592-641f-4300-96c4-819fafb6435a",
    "createdAt": "2026-02-09T21:20:05.269Z",
    "updatedAt": "2026-02-09T21:20:05.269Z",
    "enterpriseId": "698a2f58718d0f73eb4ba9faeb491be0",
    "name": "roychon401+30@bitgo.com",
    "owner": "698a2f58718d0f73eb4ba9faeb491be0"
}
```

### 1.2 Create Listing Entry

Create an entry for your Go Account within your enterprise listing. This enables you and others to create connections between your Go Account and theirs.

>Endpoint: [Create a Listing Entry](/reference/v1postlistingentryroute)

```shell cURL
export ACCESS_TOKEN="<SERVICE_USER_ACCESS_TOKEN>"
export WALLET_ID="<YOUR_WALLET_ID>"
export DESCRIPTION="<YOUR_PUBLIC_DESCRIPTION>"

curl -X POST \
  https://app.bitgo-test.com/api/address-book/v1/listing/entry/global \
  -H 'Content-Type: application/json' \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -d '{
    "walletId": "'"$WALLET_ID"'",
    "description": "'"$DESCRIPTION"'",
    "public": true
  }'
```

#### Step Result

```json JSON
{
    "walletId": "698a3d58066a618a569a8dd844c514d4",
    "type": "GO_ACCOUNT",
    "coin": "ofc",
    "discoverable": true,
    "featured": false,
    "id": "a2a48c3c-5ab1-46ab-bd05-59082576c5c2",
    "createdAt": "2026-02-09T21:29:26.194Z",
    "updatedAt": "2026-02-09T21:29:26.194Z"
}
```

### 1.3 Get your Listing Entry ID

Get the enterprise listing and select the entry that has your Go Account `walletId`. 

>Endpoint: [Get enterprise listing](/reference/v1getlistingroute)

```shell cURL
export ACCESS_TOKEN="<SERVICE_USER_ACCESS_TOKEN>"
export CHILD_ENTERPRISE_ID="<CHILD_ENTERPRISE_ID>"
export USER_ID="<YOUR_USER_ID>"

curl -X GET \
  https://app.bitgo-test.com/api/address-book/v1/listing/global \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "enterprise-id: $CHILD_ENTERPRISE_ID" \
  -H "user-id: $USER_ID"
```

#### Step Result

The `listingEntryId` is `listingEntries[<index>].id`.

```json JSON
{
    "id": "10b51fd8-6ef7-4ad1-8a84-56f84abfec7a",
    "createdAt": "2026-01-14T15:31:45.292Z",
    "updatedAt": "2026-01-14T15:31:45.292Z",
    "enterpriseId": "6967afd69792fa80c629f22bb52caed6",
    "name": "Test User",
    "owner": "6967afd69792fa80c629f22bb52caed6",
    "listingEntries": [
        {
            "id": "1a7b6239-8412-4702-b000-b40ee5351761",
            "createdAt": "2026-01-14T15:31:46.052Z",
            "updatedAt": "2026-01-14T15:31:46.052Z",
            "walletId": "6967b45a4ffdedb5747d5934e544b94c",
            "coin": "ofc",
            "type": "GO_ACCOUNT",
            "discoverable": false,
            "featured": false
        }
    ]
}
```

### 1.4 Create Counterparty Connection

> 📘 **Note**
>
> The following difference when creating a counterparty connection:

- For a listed counterparty, pass your `listingEntryId` and their `targetListingEntryId`.
- For an unlisted counterparty, pass your `listingEntryId` and their Go Account `walletId`. You must also label the connection using the `localListingName` parameter.
- For a counterparty that's in the same organization as you, pass their `walletId`.

>Endpoint: [Add Go Account connection](/reference/v1postconnectionroute)

```shell cURL (Listed)
export ACCESS_TOKEN="<SERVICE_USER_ACCESS_TOKEN>"
export CHILD_ENTERPRISE_ID="<CHILD_ENTERPRISE_ID>"
export USER_ID="<YOUR_USER_ID>"
export LISTING_ENTRY_ID="<YOUR_LISTING_ENTRY_ID>"
export TARGET_LISTING_ENTRY_ID="<COUNTERPARTY_TARGET_LISTING_ENTRY_ID>"
export LOCAL_LISTING_ENTRY_DESCRIPTION="<LOCAL_LISTING_ENTRY_DESCRIPTION>"

curl -X POST \
  https://app.bitgo-test.com/api/address-book/v1/connections \
  -H 'Content-Type: application/json' \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "enterprise-id: $CHILD_ENTERPRISE_ID" \
  -H "user-id: $USER_ID" \
  -d '{
    "listingEntryId": "'"$LISTING_ENTRY_ID"'",
    "localListingEntryDescription": "'"$LOCAL_LISTING_ENTRY_DESCRIPTION"'",
    "targetListingEntryId": "'"$TARGET_LISTING_ENTRY_ID"'"
  }'
```
```shell cURL (Unlisted)
export ACCESS_TOKEN="<SERVICE_USER_ACCESS_TOKEN>"
export CHILD_ENTERPRISE_ID="<CHILD_ENTERPRISE_ID>"
export USER_ID="<YOUR_USER_ID>"
export LISTING_ENTRY_ID="<YOUR_LISTING_ENTRY_ID>"
export COUNTERPARTY_WALLET_ID="<COUNTERPARTY_GO_ACCOUNT_WALLET_ID>"
export LOCAL_LISTING_NAME="<LOCAL_LISTING_NAME>"

curl -X POST \
  https://app.bitgo-test.com/api/address-book/v1/connections \
  -H 'Content-Type: application/json' \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "enterprise-id: $CHILD_ENTERPRISE_ID" \
  -H "user-id: $USER_ID" \
  -d '{
    "localListingName": "'"$LOCAL_LISTING_NAME"'",
    "listingEntryId": "'"$LISTING_ENTRY_ID"'",
    "walletId": "'"$COUNTERPARTY_WALLET_ID"'"
  }'
```

#### Step Result

```json JSON
{
    "connections": [
        {
            "id": "eafc174e-d1b9-4baf-ba78-275e6d699850",
            "createdAt": "2026-01-14T18:14:20.015Z",
            "updatedAt": "2026-01-14T18:14:20.275Z",
            "label": "DVP connection from 6967b45a4ffdedb5747d5934e544b94c to 6967dbd76e03e014ca3ccec6839a046a",
            "status": "ACTIVE",
            "createdBy": "695d68b062ce13d38fa6a3ec72df6e4c",
            "updatedBy": "695d68b062ce13d38fa6a3ec72df6e4c",
            "hidden": false,
            "type": "DVP",
            "ownerListingEntry": {
                "id": "1a7b6239-8412-4702-b000-b40ee5351761",
                "createdAt": "2026-01-14T15:31:46.052Z",
                "updatedAt": "2026-01-14T15:31:46.052Z",
                "walletId": "6967b45a4ffdedb5747d5934e544b94c",
                "coin": "ofc",
                "type": "GO_ACCOUNT",
                "discoverable": false,
                "featured": false,
                "listing": {
                    "id": "10b51fd8-6ef7-4ad1-8a84-56f84abfec7a",
                    "name": "Test User",
                    "editable": false
                }
            },
            "targetListingEntry": {
                "id": "8a4cae30-7473-4301-988e-d01eba0d6177",
                "createdAt": "2026-01-14T18:14:20.015Z",
                "updatedAt": "2026-01-14T18:14:20.015Z",
                "walletId": "6967dbd76e03e014ca3ccec6839a046a",
                "coin": "ofc",
                "type": "GO_ACCOUNT",
                "discoverable": false,
                "featured": false,
                "listing": {
                    "id": "34d9f5d2-cd8d-4214-acda-e5693e02a977",
                    "name": "Test Go Account",
                    "editable": true
                }
            }
        }
    ]
}
```

### 2. Create Settlement

BitGo refers to the Go Account that creates a counterparty connection and initiates a settlement as the source Go Account. When a source Go Account creates a settlement, BitGo generates a settlement request that requires approval from both counterparties. To learn more, see [Settlements](/docs/go-network-settle-overview).

Identify your counterparty for a settlement using the `id` and the `updatedAt` values that you received in the prior step or by calling the [Lists counterparty Go Account connections](/reference/v1getcounterpartyconnectionsroute) endpoint. These fields map to `addressBookConnectionId` and `addressBookConnectionUpdatedAt`.

#### Understanding the Quantity Field

The `quantity` field determines the direction of fund movement from your account perspective:

| Quantity | Direction | Description |
| :--- | :--- | :--- |
| **Positive** (for example, `"20000"`) | Receiving | Funds enter your account. You are receiving money from the counterparty. |
| **Negative** (for example, `"-20000"`) | Sending | Funds leave your account. You are sending money to the counterparty. |

>Endpoint: [Create settlement](/reference/v1enterpriseaccountsettlementpostroute)

```shell cURL
export CHILD_ENTERPRISE_ID="<CHILD_ENTERPRISE_ID>"
export ACCOUNT_ID="<YOUR_ACCOUNT_ID>"
export ACCESS_TOKEN="<SERVICE_USER_ACCESS_TOKEN>"
export CONNECTION_ID="<CONNECTION_ID>"
export CONNECTION_UPDATED_AT="<CONNECTION_UPDATED_AT>"
export COUNTERPARTY_ACCOUNT_ID="<COUNTERPARTY_ACCOUNT_ID>"
export CURRENCY="<SENDING_ASSET>"
export QUANTITY="<SENDING_QUANTITY>"
export EXTERNAL_ID="<YOUR_EXTERNAL_ID>" # Any UUID you generate and persist for tracking/idempotency on your side

curl -X POST \
  https://app.bitgo-test.com/api/clearing/v1/enterprise/$CHILD_ENTERPRISE_ID/account/$ACCOUNT_ID/settlement \
  -H 'Content-Type: application/json' \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -d '{
    "externalId": "'"$EXTERNAL_ID"'",
    "addressBookConnectionId": "'"$CONNECTION_ID"'",
    "addressBookConnectionUpdatedAt": "'"$CONNECTION_UPDATED_AT"'",
    "assetTransfers": [
      {
        "currency": "'"$CURRENCY"'",
        "quantity": "'"$QUANTITY"'"
      }
    ]
  }'
```

#### Step Result

```json JSON
{
  "id": "string",
  "requesterAccountId": "string",
  "status": "pending",
  "type": "direct",
  "externalId": "string",
  "bypassCounterpartySigning": false,
  "createdAt": "2019-08-24T00:00:00.000Z",
  "updatedAt": "2019-08-24T00:00:00.000Z",
  "approvalRequests": [
    {
      "id": "23d3e6c5-72d2-41e8-9e79-8d7e09a19b74",
      "accountId": "yourAccountId",
      "status": "acknowledged",
      "payload": "{\"nonce\":\"abc123\",\"version\":\"3.0.0\",\"signerAccount\":\"yourAccountId\",\"settlementTransfers\":[]}",
      "createdAt": "2019-08-24T00:00:00.000Z",
      "updatedAt": "2019-08-24T00:00:00.000Z"
    }
  ],
  "settlementTransfers": [
    {
      "id": "b5f1ab55-b510-4bf6-92cd-214a7e23321",
      "sourceTradingAccountId": "yourAccountId",
      "destinationTradingAccountId": "counterpartiesAccountId",
      "currency": "ofctsol",
      "quantity": "1",
      "txIds": [],
      "createdAt": "2019-08-24T00:00:00.000Z",
      "updatedAt": "2019-08-24T00:00:00.000Z"
    }
  ],
  "requesterAccountName": "string"
}
```

### 3. Sign Settlement (Optional)

If you're sending assets in the settlement, you must sign the settlement to confirm the transaction. However, if you're only receiving assets in a settlement, signing is optional.

### 3.1 Apply Signature

```js JavaScript
import { BitGoAPI } from '@bitgo/sdk-api';
import { coins } from '@bitgo/sdk-core';

const OFC_WALLET_ID = process.env.OFC_WALLET_ID;
const payload = process.env.PAYLOAD;
const walletPassphrase = process.env.OFC_WALLET_PASSPHRASE;

const bitgo = new BitGoAPI({
  accessToken: process.env.TESTNET_ACCESS_TOKEN,
  env: 'test',
});

const coin = 'ofc';
bitgo.register(coin, coins.Ofc.createInstance);

async function main() {
  const wallet = await bitgo.coin('ofc').wallets().get({ id: OFC_WALLET_ID });

  console.log('Wallet:', wallet);

  const tradingAccount = wallet.toTradingAccount();

  const signature = tradingAccount.signPayload({payload, walletPassphrase});

  console.log('Signature:', signature);
}

main().catch((e) => console.error(e));
```


#### Substep Result

```
"1f2f62b22832940d82819eccc9e2fbcb5339ae863bc9fba4d6cc62f01550fc325a7e007fb8b753d0e862145e716d4a6054f75c2da2b7c2ac5d41679683a4996349"
```

### 3.2 Submit Signed Settlement

>Endpoint: [Sign settlement](/reference/v1postsettlementsigningroute)

```shell cURL
export ENTERPRISE_ID="<YOUR_ENTERPRISE_ID>"
export ACCOUNT_ID="<YOUR_ACCOUNT_ID>"
export SETTLEMENT_ID="<SETTLEMENT_ID>"
export ACCESS_TOKEN="<SERVICE_USER_ACCESS_TOKEN>"
export PAYLOAD="<SETTLEMENT_PAYLOAD>"
export SIGNATURE="<YOUR_PUBLIC_KEY>"

curl -X POST \
  https://app.bitgo-test.com/api/clearing/v1/enterprise/$ENTERPRISE_ID/account/$ACCOUNT_ID/settlement/$SETTLEMENT_ID/signing \
  -H 'Content-Type: application/json' \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -d '{
    "payload": "'"$PAYLOAD"'",
    "signature": "'"$SIGNATURE"'"
  }'
```

#### Substep Result

Signing a settlement places the assets in your Go Account into a `held` state, preventing them from use in other transactions. If your Go Account has an insufficient balance to cover the settlement, BitGo rejects the request.

> 📘 **Note**
>
> If the signing fails for any reason, the settlement cancels.

```json JSON
{}
```

### 4. Approve Settlement (Optional)

> 📘 **Note**
>
> If you configure an approval requirement for settlements, you can't approve a settlement you initiated - another admin must always approve it.

>Endpoint: [Update Pending Approval](/reference/v2approvalupdate)

```shell cURL
export APPROVAL_ID="<APPROVAL_ID>"
export ACCESS_TOKEN="<SERVICE_USER_ACCESS_TOKEN>"
export OTP="<YOUR_OTP>"

curl -X PUT \
  https://app.bitgo-test.com/api/v2/pendingApprovals/$APPROVAL_ID \
  -H 'Content-Type: application/json' \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -d '{
    "state": "approved",
    "otp": "'"$OTP"'"
  }'
```
```js JavaScript
const baseCoin = this.bitgoSDK.coin(initialPendingApproval.coin);
const pendingApproval = await baseCoin.pendingApprovals().get({ id: initialPendingApproval.id });
const result = await pendingApproval.approve(params);
```

#### Step Result

```json JSON
{
    "id": "65529448bd87efe59c3b0156ddfce867",
    "coin": "tbtc4",
    "wallet": "654ec786c07fe8dc0dcfe03916ec5bb0",
    "enterprise": "62c5ae8174ac860007aff138a2d74df7",
    "creator": "62ab90e06dfda30007974f0a52a12995",
    "createDate": "2023-11-13T21:25:28.022Z",
    "info": {
        "type": "transactionRequest",
        "transactionRequest": {
            "requestedAmount": "10000",
            "fee": 20451,
            "sourceWallet": "654ec786c07fe8dc0dcfe03916ec5bb0",
            "policyUniqueId": "654ec786c07fe8dc0dcfe03f",
            "recipients": [
                {
                    "address": "2N1UvKhtSHLUa9YomSH7n9YMFCkMG2pbmsQ",
                    "amount": "10000",
                    "_id": "65529448bd87efe59c3b0158"
                }
            ],
            "coinSpecific": {
                "tbtc4": {
                    "txHex": "010000000001010e4d3af014f9efe311062965d561b67f78a1759e7016605cd506ddd7041762d50000000023220020510ded26d712922bbb61bc68ef6766f836a03527820cbdc8b1551914eb467dafffffffff02102700000000000017a9145a581567fd2a630e61e34a696ab3bb887972886d87ad0f010000000000225120850d0ab466d15cb1565dd528d4d9709f3e46f41d41fe6d94aa01378e626983990500483045022100db45a8d94ee2144f7e29baa855d94a2bf0120707a7ab2fc93734ed94af972c460220558d00b91275aafc7805dfaaf9ab796adbe9f4e66dc467f7eb93b790671a323201000069522103c10ac628c880629ed0fd2a0563a898f4882baca45e15668a4d3064cf1ea379882103e56f84be4460080618ef869bb7b07096880760f748ba23efab533c2359f923bd21020ae81372264b5eac5c9dc7fe0b9a32bad00771c3a2c71f6e2c971823c3182ed653ae00000000"
                }
            },
            "validTransaction": "010000000001010e4d3af014f9efe311062965d561b67f78a1759e7016605cd506ddd7041762d50000000023220020510ded26d712922bbb61bc68ef6766f836a03527820cbdc8b1551914eb467dafffffffff02102700000000000017a9145a581567fd2a630e61e34a696ab3bb887972886d87ad0f010000000000225120850d0ab466d15cb1565dd528d4d9709f3e46f41d41fe6d94aa01378e626983990400483045022100db45a8d94ee2144f7e29baa855d94a2bf0120707a7ab2fc93734ed94af972c460220558d00b91275aafc7805dfaaf9ab796adbe9f4e66dc467f7eb93b790671a323201473044022049e20c0073f42c9636408efc6c833ebf0e1a8ef13e8cb818dde2f4e2af7f7b7f022000cb3a321d65605b9d51d7f87e34306169607646c8d54a44011b021eff3dbe500169522103c10ac628c880629ed0fd2a0563a898f4882baca45e15668a4d3064cf1ea379882103e56f84be4460080618ef869bb7b07096880760f748ba23efab533c2359f923bd21020ae81372264b5eac5c9dc7fe0b9a32bad00771c3a2c71f6e2c971823c3182ed653ae00000000",
            "validTransactionHash": "5ea8d2b93997ed9fa3597a2f3113817c8216f573a0278c2533bb5db50fdb0dff"
        }
    },
    "state": "approved",
    "scope": "wallet",
    "userIds": [
        "62ab90e06dfda30007974f0a52a12995",
        "621d08a634ad8a0007fcddffd7c429cc"
    ],
    "approvalsRequired": 1,
    "singleRunResults": [
        {
            "ruleId": "Custody Enterprise Transaction ID Verification",
            "triggered": false,
            "_id": "65529448bd87efe59c3b0157"
        }
    ],
    "resolvers": [
        {
            "user": "621d08a634ad8a0007fcddffd7c429cc",
            "date": "2023-11-13T21:44:27.794Z",
            "resolutionType": "pending"
        }
    ]
}
```
</Tab>
</Tabs>

## See Also

* [CaaS Overview](/docs/crypto-as-a-service-overview)
* [API Reference: Add bank account](/reference/v2bankaccountadd)
* [API Reference: Get bank account](/reference/v2bankaccountget)
* [API Reference: Get Enterprise Transfer Limits](/reference/tradfiv1enterprisetransferlimits)
* [API Reference: Create Plaid Link token](/reference/tradfiv1plaidlinktokencreate)
* [API Reference: Exchange Plaid Public Token](/reference/tradfiv1plaidlinktokenexchange)
* [API Reference: Get Deposit Info](/reference/fiatgetdepositinfo)
* [API Reference: Create a Bank Transfer](/reference/tradfiv1bank-transferscreate)
* [API Reference: Get a Bank Transfer](/reference/tradfiv1bank-transfersget)
* [API Reference: Build a Transaction](/reference/v2wallettxbuild)
* [API Reference: List Bank Accounts](/reference/v2bankaccountlist)
* [API Reference: Update Pending Approval](/reference/v2approvalupdate)
* [API Reference: Send Half-Signed Transaction](/reference/v2wallettxsend)
* [API Reference: Create settlement](/reference/v1enterpriseaccountsettlementpostroute)
* [API Reference: Sign settlement](/reference/v1postsettlementsigningroute)
* [API Reference: Update Pending Approval](/reference/v2approvalupdate)
* [API Reference: Update settlement approval request](/reference/v1approvalrequestputroute)
