> ## Documentation Index
> Fetch the complete documentation index at: https://www.bitnob.dev/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> Bitnob API requests authenticate with an `X-Auth-Client` API key header against https://api.bitnob.com.
> Always use the sandbox environment for testing. Never put live API keys in sample code.
> Money amounts are integers in the smallest unit of the currency (satoshis for BTC, cents for fiat). Never use floats.
> Every state-changing request takes a client-supplied `reference` and must be treated as idempotent on retry.
> Quotes expire. Re-quote rather than reusing a stale quote id.

# Bitnob Enterprise API webhooks

> The two kinds of Bitnob Enterprise webhook, the events each one sends, and how to verify every delivery's signature.

The Bitnob Enterprise API sends two kinds of webhook. They're signed the same way, but the signature arrives in a different place.

| | Enterprise webhooks | On-chain subscriptions |
| - | - | - |
| Created with | [Create webhook](https://www.bitnob.dev/api-reference/platform/webhooks/create-webhook.md) | [Create subscription](https://www.bitnob.dev/api-reference/platform/subscriptions/create-subscription.md) |
| What they report | Activity in your organization: wallets, transactions, gas stations, policies, KYT | Activity on addresses you watch: incoming and outgoing transfers, confirmations, balance changes |
| Signature | `X-Webhook-Signature` header | `signature` field in the JSON body |

## Events

Enterprise webhooks deliver events such as `wallet.created`, `transaction.signed`, `transaction.confirmed`, `transaction.completed`, `transaction.failed`, `gas_station.low_balance`, `policy.violation`, and `kyt.deposit.flagged`. [List supported event types](https://www.bitnob.dev/api-reference/platform/webhooks/list-supported-event-types.md) returns the full, current list.

On-chain subscriptions deliver events such as `incoming_native_tx`, `incoming_token_tx`, `outgoing_native_tx`, `confirmation_threshold_met`, `confirmation_finalized`, and `balance_changed`.

## Verify every delivery

Each webhook and subscription has a signing secret. It's shown once, when you create it or rotate it with the rotate-secret endpoint, so store it then.

The signature is computed over a canonical JSON object built from three fields of the delivery, and nothing else:

```text theme={null}
{"data": <data>, "event": "<event>", "timestamp": <unix_seconds>}
```

```text theme={null}
signature = "sha256=" + hex(HMAC_SHA256(signing_secret, canonical_json))
```

To verify a delivery:

**1. Build the canonical object**

Take `data`, `event`, and `timestamp` from the delivery and put them in a new object with the keys in that order: `data`, `event`, `timestamp`. Leave out the `signature` field and anything else in the body.

**2. Compute and compare**

Compute the HMAC-SHA256 with your signing secret, hex-encode it, and prefix it with `sha256=`. Compare it with the received value in constant time, and reject the delivery if they differ.

**3. Check the timestamp**

Reject deliveries whose `timestamp` is older than your tolerance window, a few minutes for example, so a captured delivery can't be replayed later.

> [!NOTE]
>
> The canonical object must serialize exactly as the platform's does: keys in lexical order, and Go's `encoding/json` formatting.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.