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:
Type | Triggers When |
---|---|
address_confirmation | A wallet address initializes on chain. This is only applicable for ETH and XRP. |
admin | A wallet freezes, preventing withdrawals. |
circuitBreaker | More than $20M USD withdraws from the wallet within 24 hours. |
lowFee | The average fee on a blockchain drops below a configurable threshold set on a wallet. |
lowFeeAddressBalance | Your gas tank balance is low. |
pendingapproval | There's a wallet event that requires approval. For example, pending approval state updates, policy changes, sending transactions, or user changes. |
transaction | There's a transaction recorded on chain. Returns the transaction hash. |
transactionExpire | A send request expires. |
transactionRemoved | A transaction has been removed. |
transaction_finality_on_l1 | An L2 transaction reaches finality on the L1 chain. Applies to rollup chains such as Arbitrum, Optimism, and zkSync. |
transfer | There's a transfer into or out of a wallet. |
txRequest | A transaction request state changes, such as changing from signed to pendingApproval . |
txRequestTransaction | The state of a transaction within a transaction request changes. |
Prerequisites
- Get Started
- Create Wallets
- If you want to verify webhook notifications, ensure your enterprise has a webhook secret (see Create Webhook Secret).
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
Updated 18 days ago