Create Wallet Webhooks

Overview

You can create wallet webhooks to receive an HTTP callback from BitGo to a specified URL when specific wallet events occur. Wallets can have up to 10 webhooks of each wallet-webhook type.

Note: An unconfirmed webhook notification doesn't trigger if a transaction is confirmed on chain immediately after it's sent, or if it's a Replace-by-fee (RBF) transaction.

Wallet Webhook Types

BitGo offers the following types of webhooks for wallets:

TypeTriggers When
address_confirmationA wallet address initializes on chain. This is only applicable for ETH and XRP.
adminA wallet freezes, preventing withdrawals.
circuitBreakerMore than $20M USD withdraws from the wallet within 24 hours.
lowFeeThe average fee on a blockchain drops below a configurable threshold set on a wallet.
lowFeeAddressBalanceYour gas tank balance is low.
pendingapprovalThere's a wallet event that requires approval. For example, pending approval state updates, policy changes, sending transactions, or user changes.
stuckTxA transaction that is stuck in signed state with multiple retry broadcast attempts. Applies to Ethereum and EVM-compatible chains, Cosmos-based chains, Aptos, Polkadot, and Bittensor.
transactionThere's a transaction recorded on chain. Returns the transaction hash.
transactionExpireA send request expires.
transactionRemovedA transaction has been removed.
transaction_finality_on_l1An L2 transaction reaches finality on the L1 chain. Applies to rollup chains such as Arbitrum, Optimism, and zkSync.
transferThere's a transfer into or out of a wallet.
txRequestA transaction request state changes, such as changing from signed to pendingApproval.
txRequestTransactionThe state of a transaction within a transaction request changes.

Prerequisites

1. Create Wallet Webhooks

The following example creates a webhook that notifies you whenever there's a transfer into or out of a wallet.

Endpoint: Add Wallet Webhook

export COIN="<ASSET_ID>"
export WALLET_ID="<YOUR_WALLET_ID>"
export ACCESS_TOKEN="<YOUR_ACCESS_TOKEN>"
export URL="<YOUR_WEBHOOK_URL>"
export LABEL="<YOUR_WEBHOOK_NAME>"

curl -X POST \
  https://app.bitgo-test.com/api/v2/$COIN/wallet/$WALLET_ID/webhooks \
  -H 'Content-Type: application/json' \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -d '{
    "type": "transfer",
    "url": "'"$URL"'",
    "label": "'"$LABEL"'",
    "listenToFailureStates": true,
    "customHttpHeaders": {          # Optional fields that you can customize
        "property1": "string",      # with any property names and values
        "property2": "string"
    }
  }'
const BitGo = require('bitgo');
const bitgo = new BitGo.BitGo({
  env: 'test',
  accessToken: process.env.TEST_ACCESS_TOKEN
});
bitgo.coin('tbtc4').wallets().get({
  id: '<wallet_id>'
}).then((wallet) => {
  wallet.addWebhook({
    type: 'transfer',
    allToken: false,
    url: 'http://your.server.com/webhook',
    label: '<your_webhook_label>',
    nnumConfirmations: 6,
    listenToFailureStates: true
  })
});
Step Result
{
  "id": "6853113bd6d99d1109391bc98a0dbfd5",
  "label": "my-btc-transfer-webhook",
  "created": "2025-06-18T19:19:23.127Z",
  "scope": "wallet",
  "walletId": "67536a92b294f87c998ea39f85a6bdc7",
  "coin": "tbtc4",
  "type": "transfer",
  "url": "https://webhook.site/f74addc1-c40a-4fce-879a-2d92b8d491c5",
  "version": 2,
  "state": "active",
  "successiveFailedAttempts": 0,
  "listenToFailureStates": true,
  "txRequestStates": [],
  "txRequestTransactionStates": []
}

2. (Optional) Verify Webhook Notification

You can verify the webhook notification is legitimate by passing the payload you received in the prior step as a JSON string with your webhook secret (created with the Create webhook secret endpoint).

Endpoint: Verify Webhook Notification

export WEBHOOK_ID="<YOUR_WEBHOOK_ID>"
export ACCESS_TOKEN="<YOUR_ACCESS_TOKEN>"
export SIGNATURE="<YOUR_WEBHOOK_SECRET>" # Created using the Create webhook secret endpoint
export PAYLOAD="<YOUR_PAYLOAD>" # JSON payload as a string that you received in the prior step

curl -X POST "https://app.bitgo-test.com/api/v2/webhook/$WEBHOOK_ID/verify" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -d '{
    "signature": "'"$SIGNATURE"'",
    "notificationPayload": "'"$PAYLOAD"'"
  }'
Step Result
{
  "webhookId": "wh119ecd15a4adf811f8f552fde21b9d819b4dc9a7f04c51513395816703c73511",
  "isValid": true
}

3. (Optional) Simulate Wallet Webhook

You can simulate your webhook with real data from the prior step or with placeholder data (also known as dummy data).

Endpoint: Simulate Wallet Webhook

export COIN="<ASSET_ID>"
export WALLET_ID="<YOUR_WALLET_ID>"
export WEBHOOK_ID="<YOUR_WEBHOOK_ID>"
export ACCESS_TOKEN="<YOUR_ACCESS_TOKEN>"
export TRANSFER_ID="<YOUR_TRANSFER_TOKEN>"

curl -X POST "https://app.bitgo-test.com/api/v2/$COIN/wallet/$WALLET_ID/webhooks/$WEBHOOK_ID/simulate" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $ACCESS_TOKEN"
  -d '{
  "transferId": "'"$TRANSFER_ID"'"
}'
export COIN="<ASSET_ID>"
export WALLET_ID="<YOUR_WALLET_ID>"
export WEBHOOK_ID="<YOUR_WEBHOOK_ID>"
export ACCESS_TOKEN="<YOUR_ACCESS_TOKEN>"
export TRANSFER_ID="<YOUR_TRANSFER_TOKEN>"

curl -X POST "https://app.bitgo-test.com/api/v2/$COIN/wallet/$WALLET_ID/webhooks/$WEBHOOK_ID/simulate" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $ACCESS_TOKEN"
  -d '{
  "usePlaceholderData": true
}'
Step Result
{
    "webhookNotifications": [
        {
            "id": "6853262b9da229cea98569ce71fc060e",
            "type": "transfer",
            "wallet": "62c5b5c9d0ece30007cec9616ff29edc",
            "enterprise": "62c5ae8174ac860007aff138a2d74df7",
            "organization": "62c5ae8174ac860007aff1555ffb960d",
            "url": "https://webhook.site/f74addc1-c40a-4fce-879a-2d92b8d491c5",
            "hash": "db924f4cf2347ac5a6b464d3e8dc4a20cffc117eb29f4460645fbc34de171bfb",
            "coin": "tbtc4",
            "transfer": "68531ea4e3669330070c95e454f5b366",
            "state": "new",
            "simulation": true,
            "retries": 0,
            "webhook": "68531e154d28af627819bd3e183a930e",
            "updatedAt": "2025-06-18T20:48:43.525Z",
            "version": 2,
            "idempotencyKey": "e3094fa873a8e5b5"
        }
    ]
}

Next

Before you process webhook notifications, BitGo strongly recommends that you verify response details by fetching the transfer or block data from BitGo. For example, if you create a transfer webhook and receive a transfer ID, pass that ID to the Get Transfer endpoint to verify the transfer details.

For more examples, see the BitGo JavaScript SDK GitHub repository.

See Also