Withdraw - Self-Custody Multisig (Manual)

Build, sign, and send withdrawals with granular control. See the Guide.

  1. Build the transaction by specifying transaction details and sending them to BitGo. BitGo constructs an unsigned transaction that wallet co-signers can sign.

    For UTXO assets in quick succession, reserve unspents by passing reservation and expireTime parameters to avoid errors.

    API Reference

  2. Using the txHex and txInfo returned from Build Transaction, sign the transaction using your private key. BitGo Express is required for signing.

    For external signing-mode, use the Sign Wallet Transaction endpoint instead.

    API Reference

  3. Send the half-signed transaction to BitGo. If approval is not required, BitGo applies the final signature and broadcasts to the blockchain. If you have policy rules requiring approvals, the transaction remains pending until approved.

    API Reference

  4. If your withdrawal requires approval, another admin must approve it — you cannot approve your own transactions. Once approved, BitGo rebuilds the transaction with current fees, applies the final signature, and broadcasts to the blockchain.

    API Reference

// 1. Build Transaction
export COIN="<ASSET_ID>"
export WALLET_ID="<YOUR_WALLET_ID>"
export ACCESS_TOKEN="<YOUR_ACCESS_TOKEN>"
export ADDRESS="<DESTINATION_ADDRESS>"
export AMOUNT="<AMOUNT_IN_BASE_UNITS>"

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"'"
      }
    ]
  }'
// 2. Sign Transaction
export BITGO_EXPRESS_HOST="<YOUR_LOCAL_HOST>"
export PRV="<YOUR_PRIVATE_KEY>"
export USER_PUB="<YOUR_USER_PUBLIC_KEY>"
export BACKUP_PUB="<YOUR_BACKUP_PUBLIC_KEY>"
export BITGO_PUB="<BITGO_PUBLIC_KEY>"

curl -X POST \
  http://$BITGO_EXPRESS_HOST/api/v2/$COIN/signtx \
  -H 'Content-Type: application/json' \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -d '{
    "prv": "'"$PRV"'",
    "pubs": ["'"$USER_PUB"'", "'"$BACKUP_PUB"'", "'"$BITGO_PUB"'"],
    "txPrebuild": {
      "wallet": "'"$WALLET_ID"'",
      "txHex": "<TX_HEX_FROM_STEP_1>",
      "txInfo": { },
      "feeInfo": { },
      "coin": "'"$COIN"'"
    }
  }'
// 3. Send Transaction
curl -X POST \
  https://app.bitgo-test.com/api/v2/$COIN/wallet/$WALLET_ID/tx/send \
  -H 'Content-Type: application/json' \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -d '{
    "halfSigned": {
      "txHex": "<HALF_SIGNED_TX_HEX_FROM_STEP_2>"
    }
  }'
// 4. Approve Transaction (Optional)
export APPROVAL_ID="<APPROVAL_ID>"
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"'"
  }'
Response
// 1. Build Transaction Response
{
  "txHex": "01000000010e4d3af014f9efe311062965d561b67f78a1759e...",
  "txInfo": {
    "nP2SHInputs": 0,
    "nSegwitInputs": 1,
    "nOutputs": 2,
    "unspents": [{ "chain": 10, "index": 5, "value": 100000 }],
    "changeAddresses": ["tb1ps5xs4drx69wtz4ja655dfktsnulydaqag8lxm992qymcucnfswvspwdwxq"]
  },
  "feeInfo": {
    "size": 226,
    "fee": 20451,
    "feeRate": 90491
  },
  "coin": "tbtc4"
}

// 2. Sign Transaction Response
{
  "txHex": "010000000001010e4d3af014f9efe311062965d561b67f78a1759e..."
}

// 3. Send Transaction Response (approval not required)
{
  "transfer": {
    "id": "65528cde229f765c57a8f4d1eb762908",
    "coin": "tbtc4",
    "txid": "c68916ddc1672ec62c474ef0839ec479ad9b2dabc2249177ce6be6247f81dfe7",
    "state": "signed",
    "type": "send",
    "value": -29987
  },
  "txid": "c68916ddc1672ec62c474ef0839ec479ad9b2dabc2249177ce6be6247f81dfe7",
  "status": "signed"
}

// 3. Send Transaction Response (pending approval)
{
  "error": "triggered all transactions policy",
  "pendingApproval": {
    "id": "65529448bd87efe59c3b0156ddfce867",
    "state": "pendingApproval",
    "approvalsRequired": 1
  }
}

// 4. Approve Transaction Response
{
  "id": "65529448bd87efe59c3b0156ddfce867",
  "state": "approved",
  "info": {
    "transactionRequest": {
      "validTransactionHash": "5ea8d2b93997ed9fa3597a2f3113817c8216f573a0278c2533bb5db50fdb0dff"
    }
  }
}