Create Webhook Policy Rules

Create webhook policy rules to enforce custom business logic for approving or denying transactions. See the Guide.

  1. This example creates a webhook policy rule that denies a transaction when your server returns a non-200 response. When you initiate a transaction from this wallet, BitGo sends a POST request to your webhook URL. If your server responds with anything other than HTTP 200, BitGo blocks the transaction.

    Prerequisites:

    API Reference

  2. This example creates a webhook policy rule that requires approval from a specified user when your server returns a non-200 response. If your server responds with a non-200 status code, the transaction enters a pending-approval state. It does not proceed until the specified user approves it. To learn how to resolve pending approvals, see Update Policy Rules.

    API Reference

  3. When a transaction triggers a webhook policy, BitGo sends a POST request to your URL. The payload includes the wallet ID, rule ID, spend amount, approval count, half-signed transaction hex, and an array of transaction outputs. You can use this data to run custom checks, such as verifying destination addresses against an internal allowlist or checking spend amounts against your own limits.

// 1. Create a Deny Policy
export COIN="<ASSET_ID>"
export WALLET_ID="<YOUR_WALLET_ID>"
export ACCESS_TOKEN="<YOUR_ACCESS_TOKEN>"
export WEBHOOK_URL="<YOUR_WEBHOOK_URL>"

curl -X POST \
  https://app.bitgo-test.com/api/v2/$COIN/wallet/$WALLET_ID/policy/rule \
  -H 'Content-Type: application/json' \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -d '{
    "id": "my-custom-webhook-deny-rule",
    "type": "webhook",
    "condition": {
      "url": "'"$WEBHOOK_URL"'"
    },
    "action": {
      "type": "deny"
    }
  }'
// 2. Create an Approval Policy
export COIN="<ASSET_ID>"
export WALLET_ID="<YOUR_WALLET_ID>"
export ACCESS_TOKEN="<YOUR_ACCESS_TOKEN>"
export WEBHOOK_URL="<YOUR_WEBHOOK_URL>"
export APPROVER_USER_ID="<APPROVER_USER_ID>"

curl -X POST \
  https://app.bitgo-test.com/api/v2/$COIN/wallet/$WALLET_ID/policy/rule \
  -H 'Content-Type: application/json' \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -d '{
    "id": "my-custom-webhook-approval-rule",
    "type": "webhook",
    "condition": {
      "url": "'"$WEBHOOK_URL"'"
    },
    "action": {
      "type": "getApproval",
      "approvalsRequired": 1,
      "userIds": ["'"$APPROVER_USER_ID"'"]
    }
  }'
// 3. Review the Webhook Request Payload
// BitGo sends this POST request payload to your webhook URL when a transaction triggers the policy.
// See the Response Example tab for the payload format.
Response
// 3. Review the Webhook Request Payload
{
  "walletId": "5fb34d22bbd86300328d60813fcd7906",
  "ruleId": "my-custom-webhook-deny-rule",
  "type": "webhook",
  "spendAmount": "200000",
  "approvalCount": 0,
  "halfSigned": {
    "txHex": "01000000000101c92fd8e311fe..."
  },
  "outputs": [
    {
      "address": "2MzVfLyXXXjLBQdA6D8gY6DM9hR1XdJkZjR",
      "value": 200000,
      "wallet": "5ef52bdc4ba8da93002ae504e3fa89d0"
    },
    {
      "address": "2NA5QxTc2rDi18fgWrZCNoaa9ktp5ucWeFC",
      "value": 814469,
      "wallet": "5fb34d22bbd86300328d60813fcd7906"
    }
  ]
}