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

JurisdictionCurrencyPayment Rails
United StatesUSDACH debit, domestic and international wire transfers, CUBIX transfers, Go Network
EuropeEUROSEPA Instant, SEPA, BLINC transfers, Go Network

Prerequisites

Deposit Instructions

You can fetch your enterprise deposit instructions using the Get deposit info 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 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 be used for fiat operations immediately after approval. You can see the status of the bank account by calling the Get bank account endpoint and checking the verificationState field.

Approval Requirements

To ensure your bank account is approved, verify the following requirements are met:

RequirementDescription
Valid Routing NumberFor US bank accounts, provide a valid 9-digit ABA routing number. BitGo validates routing numbers against the Federal Reserve's directory. Invalid routing numbers result in rejection.
Owner Name MatchThe 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 TypeYou 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

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"
  }'
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.

{
  "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

One of the following verification states is returned:

  • pending - Bank account is under review. Most accounts are approved within 48 hours.
  • approved - Bank account is approved and ready for fiat operations.
  • rejected - Bank account is rejected. Review the requirements and resubmit.
  • revise - Bank account requires corrections. Update the account and resubmit.
  • removed - Bank account is removed from the enterprise.

Note: Use the Get bank account endpoint to check the current verification status before initiating fiat operations.

Steps

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

ACH Deposits

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

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

Before initiating ACH deposits, your platform must fund a fraud 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.
  • Must be replenished within 5 business days if funds are withdrawn.

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.

1. 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

Note: In the test environment, ACH deposits are limited to $2,500/day and $10,000/week per enterprise. Use reasonable amounts and check remaining limits to avoid exceeding these thresholds during testing.

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

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

2. Get ACH Agreement

Get the ACH agreement for a BitGo-approved bank by passing the bank ID. You can view all your bank accounts by calling the Get Bank Accounts endpoint

Endpoint: Get ACH Agreement

export AMOUNT="<AMOUNT_TO_DEPOSIT>"
export BANK_ID="<BANK_ID>"
export ACCESS_TOKEN="<SERVICE_USER_ACCESS_TOKEN>"

curl -X GET \
  "https://app.bitgo-test.com/api/fiat/v1/transaction/ach-debit/agreement?amount=$AMOUNT&bankId=$BANK_ID" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

Note: The query parameter amount is in base units (cents), but the agreement an amount in dollars.

Step Result

{
  "achAuthorizationLanguage": {
    "reviewAuthorization": "string",
    "accountInformation": {
      "accountHolderName": "string",
      "bankName": "string",
      "accountNumber": "string",
      "routingNumber": "string",
      "accountType": "checking"
    },
    "authorizationDetails": "string",
    "acknowledgment": "string"
  }
}

3. Initiate ACH Deposit

If you agree to the ACH agreement, you can proceed to initiate an ACH deposit.

Endpoint: Initiate ACH Deposit

export ACCESS_TOKEN="<SERVICE_USER_ACCESS_TOKEN>"
export AMOUNT="<AMOUNT_TO_DEPOSIT>"
export BANK_ID="<BANK_ID>"
export BANK_ID="<GO_ACCOUNT_ID>"

curl -X POST https://app.bitgo-test.com/api/fiat/v1/transaction/ach-debit \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -d '{
    "amount": "$AMOUNT",
    "checkboxAgreement": true,
    "bankId": "'"$BANK_ID"'",
    "goAccountId": "'"$GO_ACCOUNT_ID"'"
  }'

Step Result

{
  "txId": "string"
}

ACH Withdrawals

ACH withdrawals transfer USD from Go Accounts to BitGo-approved US bank accounts. ACH withdrawals are best for:

  • Low-to-medium value withdrawals.
  • Recurring user withdrawals.
  • Settlements that can wait 1–2 business days to settle.

ACH withdrawals must have a BitGo-approved bank for the recipient and are subject to standard ACH cutoff windows.

ACH withdrawals follow the same steps as a wire withdrawal. See the wire withdrawals section for integration steps.

See Also