Crypto-as-a-Service: Withdraw Fiat to Bank Account

Withdraw fiat from your Go Account to an approved bank account through ACH or wire transfer. See the Guide.

  1. Add a BitGo-approved bank account to your enterprise for fiat withdrawals. Bank accounts go through a screening process and BitGo typically approves them within 48 hours. The account must meet requirements including a valid routing number, matching owner name, and specified account type.

    If you previously added a bank account for funding and plan to use the same account for withdrawals, you can skip this step.

    API Reference

  2. Retrieve the list of bank accounts for your enterprise to get the unique idHash identifier. This idHash is used as the address value when building the withdrawal transaction in the next step.

    API Reference

  3. Build the fiat withdrawal transaction by specifying the amount and destination bank account (using the idHash as the address). BitGo constructs an unsigned transaction with the provided details.

    API Reference

  4. Authenticate the transaction using your Go Account passphrase. For security, never transmit the passphrase over the Internet. Use BitGo Express in external-signing mode or the JavaScript SDK to sign the payload locally.

    API Reference

  5. Submit the half-signed transaction to BitGo for processing. The transaction includes the signed payload from the previous step and BitGo Bank & Trust operators review it before final approval.

    API Reference

  6. You must confirm or reject each fiat withdrawal before BitGo processes the transaction. You can automate this by subscribing to the organization transfer webhook and calling the Confirm fiat withdrawal endpoint whenever you receive a fiat withdrawal event.

    If you configure a liveness check policy for automatic approvals, withdrawals that pass liveness verification confirm automatically.

    API Reference

  7. If you configured an approval requirement for withdrawals, another wallet admin must approve the transaction. Note that you cannot approve your own transactions when you enable approval policies.

    API Reference

// 1. Add Bank Account
export SERVICE_USER_TOKEN="<SERVICE_USER_ACCESS_TOKEN>"
export ENTERPRISE_ID="<CHILD_ENTERPRISE_ID>"

curl -X POST \
  https://app.bitgo-test.com/api/v2/bankaccounts \
  -H 'Content-Type: application/json' \
  -H "Authorization: Bearer $SERVICE_USER_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"
  }'

// 2. Get idHash
export ENTERPRISE_ID="<ENTERPRISE_ID>"
export SERVICE_USER_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 $SERVICE_USER_TOKEN"

// 3. Build Transaction
export COIN="<FIAT_ASSET_ID>" # Fiat asset IDs in Go Accounts always start with "ofc" (such as ofctusdt)
export WALLET_ID="<YOUR_WALLET_ID>"
export SERVICE_USER_TOKEN="<SERVICE_USER_ACCESS_TOKEN>"
export AMOUNT="<AMOUNT_IN_BASE_UNITS>"
export ADDRESS="<ID_HASH>" # 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 $SERVICE_USER_TOKEN" \
  -d '{
    "recipients": [
      {
        "amount": "'"$AMOUNT"'",
        "address": "'"$ADDRESS"'"
      }
    ]
}'

// 4. Authenticate Transaction
export BITGO_EXPRESS_HOST="<YOUR_LOCAL_HOST>"
export SERVICE_USER_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 $SERVICE_USER_TOKEN" \
  -d '{
   "walletId": "'"$WALLET_ID"'",
   "walletPassphrase": "'"$WALLET_PASSPHRASE"'",
   "payload": "{\"coin\":\"ofcusdt\",\"recipients\":[{\"address\":\"tb1q5mwcr2749nnm5c5d6rzx5h92l2u9ex5jzygzd39vfv9qerj5fmjqwlgy4t\",\"amount\":\"1000\"}],\"fromAccount\":\"67ab85b5190bf872e84da2b6e527d9f3\",\"nonce\":\"77d91a11-a7fa-4ad7-91e5-f054328717f9\",\"timestamp\":\"2025-06-26T15:02:06.924Z\",\"feeString\":\"0\",\"shortCircuitBlockchainTransfer\":false,\"isIntraJXTransfer\":false}"
}

// 5. Send Transaction
export WALLET_ID="<YOUR_WALLET_ID>"
export SERVICE_USER_TOKEN="<SERVICE_USER_ACCESS_TOKEN>"
export ADDRESS="<ID_HASH>"
export COIN="<FIAT_ASSET_ID>"
export AMOUNT="<AMOUNT_IN_BASE_UNITS>"

curl -X POST \
  https://app.bitgo-test.com/api/v2/$COIN/wallet/$WALLET_ID/tx/send \
  -H 'Content-Type: application/json' \
  -H "Authorization: Bearer $SERVICE_USER_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>"
    }
  }'

// 6. Confirm Withdrawal
export WALLET_ID="<YOUR_WALLET_ID>"
export TRANSFER_ID="<YOUR_TRANSFER_ID>"
export SERVICE_USER_TOKEN="<SERVICE_USER_ACCESS_TOKEN>"
export ACTION="<APPROVE_OR_REJECT>"
curl -X PUT \
  https://app.bitgo-test.com/api/v2/wallet/$WALLET_ID/fiatwithdrawals/$TRANSFER_ID/confirm \
  -H 'Content-Type: application/json' \
  -H "Authorization: Bearer $SERVICE_USER_TOKEN" \
  -d '{
    "action":"'"$ACTION"'"
    }'

// 7. Approve Transaction (Optional)
export COIN="<ASSET_ID>"
export APPROVAL_ID="<APPROVAL_ID>"
export SERVICE_USER_TOKEN="<SERVICE_USER_ACCESS_TOKEN>"
export OTP="<OTP>"
curl -X POST \
  https://app.bitgo-test.com/api/v2/pendingapprovals/$APPROVAL_ID \
  -H 'Content-Type: application/json' \
  -H "Authorization: Bearer $SERVICE_USER_TOKEN" \
  -d '{
    "state": "approved",
    "otp": "'"$OTP"'"
}'
Response
// 1. Add Bank Account Response
{
  "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"
}

// 2. Get idHash Response
{
    "bankAccounts": [
        {
            "type": "wire",
            "accountNumber": "012345678",
            "enterpriseId": "1032e75c451052000436831deb797af1",
            "id": "60749ab75f8c4500060f5a8b244dd0cb",
            "name": "My Bank",
            "idHash": "c2f4cf5555a66d77",
            "routingNumber": "087654321",
            "shortCountryCode": "US",
            "verificationState": "approved"
        }
    ]
}

// 3. Build Transaction Response
{
  "payload": "{\"coin\":\"ofctusdt\",\"recipients\":[{\"address\":\"tb1q5mwcr2749nnm5c5d6rzx5h92l2u9ex5jzygzd39vfv9qerj5fmjqwlgy4t\",\"amount\":\"1000\"}],\"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": "ofctusdt"
}

// 4. Authenticate Transaction Response
{
  "coin": "ofcusdt",
  "recipients": [
    {
      "address": "tb1q5mwcr2749nnm5c5d6rzx5h92l2u9ex5jzygzd39vfv9qerj5fmjqwlgy4t",
      "amount": "1000"
    }
  ],
  "fromAccount": "62c5b1de8a0c5200071c9a603bdbadc5",
  "nonce": "77d91a11-a7fa-4ad7-91e5-f054328717f9",
  "timestamp": "2025-06-26T15:02:06.924Z",
  "feeString": "0",
  "signature": "20dda1e9558adb297f69020f94cbf4955fabec73478506347dbb5ac8e73b506fc908bbc48bde75b339b99f5de808ed34b2017055c9df198fd1f8b4e524899f9583"
}

// 5. Send Transaction Response
{
    "transfer": {
        "id": "<id>",
        "coin": "ofctusd",
        "wallet": "<wallet id>",
        "walletType": "trading",
        "enterprise": "603ca88c44f82002560378421dc7a191",
        "txid": "ddd6875812fa59f899a68059ff303bfa6d39fc350ee687c407383d0444b43d2b",
        "date": "2021-09-10T22:45:21.342Z",
        "type": "send",
        "value": -10000,
        "valueString": "-10000",
        "state": "signed"
    },
    "txid": "ddd6875812fa59f899a68059ff303bfa6d39fc350ee687c407383d0444b43d2b",
    "status": "signed"
}

// 6. Confirm Withdrawal Response (Approve)
{
    "id": "6980dfc5decaa85472a63ce93f0a07a7",
    "coin": "tfiatusd",
    "wallet": "6967b45a4ffdedb5747d5934e544b94c",
    "walletType": "trading",
    "enterprise": "6967afd69792fa80c629f22bb52caed6",
    "txid": "a10d7719179b5b6705b10a6bcd2cb492c10cae15564d567d4dd3e8e699718c64",
    "date": "2026-02-02T17:33:05.285Z",
    "type": "send",
    "subType": "ofc_withdrawal",
    "value": -2100,
    "valueString": "-2100",
    "state": "pendingApproval"
}

// 6. Confirm Withdrawal Response (Reject)
{
    "id": "6980dfc5decaa85472a63ce93f0a07a7",
    "coin": "tfiatusd",
    "wallet": "6967b45a4ffdedb5747d5934e544b94c",
    "walletType": "trading",
    "enterprise": "6967afd69792fa80c629f22bb52caed6",
    "txid": "a10d7719179b5b6705b10a6bcd2cb492c10cae15564d567d4dd3e8e699718c64",
    "date": "2026-02-02T17:33:05.285Z",
    "type": "send",
    "subType": "ofc_withdrawal",
    "value": -2100,
    "valueString": "-2100",
    "state": "rejected"
}

// 7. Approve Transaction (Optional) Response
{
  "id": "655686880765186f0b3e9e88e1bdd0f4",
  "coin": "tbtc4",
  "wallet": "6553e933288be490293ae748efafeaaf",
  "enterprise": "62c5ae8174ac860007aff138a2d74df7",
  "creator": "62ab90e06dfda30007974f0a52a12995",
  "createDate": "2023-11-16T21:15:52.703Z",
  "state": "approved",
  "scope": "wallet",
  "approvalsRequired": 1
}