Create Organization Webhooks

Overview

You can create webhooks to receive an HTTP callback from BitGo to a specified URL when specific events occur. Wallets can have up to 10 webhooks of each organization-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.

Organization Webhook Types

BitGo offers the following types of organization webhooks for organizations:

TypeTriggers When
bankAccountA bank account is added.
enterpriseKycStateEnterprise KYC status changes.
identityStatusA user identity status changes.
pendingapprovalA transaction request is pending approval.
transferA transfer succeeds or fails.
txRequestA transaction request changes status.
txRequestTransactionA transaction request transaction state changes.
userKycStateA user's KYC verification status changes.

Prerequisites

1. Create Organization Webhooks

The following example creates a webhook that notifies you whenever a bank account is added.

Endpoint: Create Organization Webhook

export ORGANIZATION_ID="<YOUR_ORGANIZATION_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/organization/$ORGANIZATION_ID/webhook \
  -H 'Content-Type: application/json' \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -d '{
    "type": "bankAccount",
    "url": "'"$URL"'",
    "label": "'"$LABEL"'"
  }'
Step Result
{
  "success": "true",
  "data": {
    "id": "'690278897328c7fc41e81887d4b76964'",
    "label": "'test org webhook 1'",
    "created": "'2025-10-29T20:26:49.286Z'",
    "scope" : "'organization'",
    "organizationId" : "'68f6af3f2f29893d5863bc0eaf77b3c6'",
    "type": "bankAccount",
    "url": "'https://webhook.site/2635918b-018b-4179-82e9-6940a0b851e0'",
    "version": 1,
    "state": "active",
    "successiveFailedAttempts": "0",
    "listenToFailureStates": "false",
    "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 Organization Webhook

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

Endpoint: Simulate Enterprise Webhook

export ORGANIZATION_ID="<YOUR_ORGANIZATION_ID>"
export WEBHOOK_ID="<YOUR_WEBHOOK_ID>"
export ACCESS_TOKEN="<YOUR_ACCESS_TOKEN>"
export ACCESS_TOKEN_ID="<YOUR_ACCESS_TOKEN_ID>"

curl -X POST "https://app.bitgo-test.com/api/v2/organization/$ORGANIZATION_ID/webhook/$WEBHOOK_ID/simulate" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $ACCESS_TOKEN"
  -d '{
  "bankAccountId": "string"
}'
Step Result
{
  "webhookNotifications": [
    {
      "id": "59cd72485007a239fb00282ed480da1f",
      "accessToken": "txRequest",
      "url": "https://webhook.site/f74addc1-c40a-4fce-879a-2d92b8d491c5",
      "hash": "db924f4cf2347ac5a6b464d3e8dc4a20cffc117eb29f4460645fbc34de171bfb",
      "simulation": true,
      "retries": 0,
      "webhook": "68531e154d28af627819bd3e183a930e",
      "updatedAt": "2025-06-19T20:48:43.525Z",
      "version": 1,
      "allowBlockedHosts": true,
      "payload": "string",
      "response": {
        "code": 0,
        "type": "string",
        "body": "string",
        "error": "string"
      }
    }
  ]
}

See Also