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 |
| Europe | EURO | SEPA 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:
| 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's 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
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.
NoteUse 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 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.
Plaid Integration
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:
- Review your ACH deposit transaction history for the prior month.
- 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.
- Calculate 25% of that peak amount. Using the example above, that's $250,000.
- 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.
WarningIf 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
NoteThe 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.
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"
}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
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
}'
NoteIf 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 |
| iOS | Plaid Link for iOS |
| Android | Plaid Link for Android |
| React Native | Plaid Link for 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
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
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
{
"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.
NoteThis endpoint is only available in the test environment.
Endpoint: Create a Bank Transfer
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
{
"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's current status, settlement timestamps, and other details.
NoteThis endpoint is only available in the test environment.
Endpoint: Get Bank Transfer
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
{
"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 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
- 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).
- The risk provider returns a timeline assessment — either T+1 (low risk, advances credit) or T+4 (higher risk, does not advance credit).
- If approved, the Go Account ledger credits immediately and the funds become spendable, even though ACH settlement is still pending.
- 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
applyInstantCreditflag totrue. - 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.
ImportantInstant Credit is not guaranteed. If the risk analysis returns an unfavorable result, the deposit proceeds normally with standard settlement timing.
See Also
- CaaS Overview
- API Reference: Add bank account
- API Reference: Get bank account
- API Reference: Get Enterprise Transfer Limits
- API Reference: Create Plaid Link token
- API Reference: Exchange Plaid Public Token
- API Reference: Get Deposit Info
- API Reference: Create a Bank Transfer
- API Reference: Get a Bank Transfer
- API Reference: Build a Transaction
- API Reference: List Bank Accounts
- API Reference: Update Pending Approval
- API Reference: Send Half-Signed Transaction
- API Reference: Create settlement
- API Reference: Sign settlement
- API Reference: Update Pending Approval
- API Reference: Update settlement approval request
Updated 5 days ago