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

# Webhooks & events

> Register HTTPS endpoints, verify signed deliveries, and the full catalogue of wallet, deposit, withdrawal and signing events.

Webhooks tell your systems what happened without polling. Every state change in a wallet's life is written to the operation ledger first and then delivered to each endpoint subscribed to it, as a signed, retried, logged HTTP request.

## Register an endpoint

In the console: **Developer → Webhook → Create Webhook**. Provide an HTTPS URL, choose **All events** or a subset, add a description, and leave **Enable Webhook** on. Endpoints must be HTTPS; plain HTTP is refused.

```bash theme={null}
GET|POST   /api/v1/workspaces/{workspace_id}/webhooks              # webhooks:read | webhooks:manage
PUT|DELETE /api/v1/workspaces/{workspace_id}/webhooks/{webhook_id}
```

## Verify deliveries

Every delivery is signed with the workspace's **Ed25519** key. Fetch the public key once and verify each delivery's signature before acting on it:

```bash theme={null}
GET /api/v1/workspaces/{workspace_id}/webhook-verification-key    # returns the base64 Ed25519 public key
```

Deliveries are identified by an event ID. Treat the event ID as the idempotency key on your side: a resend carries the same ID and body with new attempt metadata.

## Retries and logs

A delivery that does not receive a `2xx` response within 10 seconds is retried with exponential backoff, starting at 30 seconds and capped at 15 minutes, for up to 10 attempts. Deliveries are then visible under **Developer → Webhook → Webhook Logs** with their status (`pending`, `delivering`, `success`, `failed`), attempt count and response code, and can be resent.

```bash theme={null}
GET  /api/v1/workspaces/{workspace_id}/webhook-logs            # ?webhook_id=&status=&event_type=
POST /api/v1/workspaces/{workspace_id}/webhook-logs/{delivery_id}/resend
GET  /api/v1/workspaces/{workspace_id}/webhook-stats
```

## Event catalogue

| Event                         | Sent when                                                            |
| :---------------------------- | :------------------------------------------------------------------- |
| `wallet.creation_requested`   | A wallet creation was recorded and key generation requested.         |
| `wallet.created`              | Key generation completed; the wallet is active.                      |
| `wallet.asset_attached`       | An asset was attached and its deposit address derived.               |
| `deposit.detected`            | An inbound transfer was observed on chain.                           |
| `deposit.failed`              | A previously detected deposit was removed by a chain reorganisation. |
| `balance.updated`             | A wallet asset's balance snapshot changed.                           |
| `withdrawal.created`          | A withdrawal request was recorded.                                   |
| `withdrawal.pending`          | The withdrawal passed validation and is being planned or signed.     |
| `withdrawal.pending_approval` | The withdrawal is held for an approval group.                        |
| `withdrawal.submitted`        | The signed transaction was broadcast.                                |
| `withdrawal.confirmed`        | The receipt reached the configured confirmation depth.               |
| `withdrawal.completed`        | The withdrawal reached its terminal successful state.                |
| `withdrawal.failed`           | The withdrawal was rejected, failed to sign, or reverted on chain.   |
| `withdrawal.cancelled`        | The withdrawal was cancelled before signing.                         |
| `signing.created`             | A direct signing request was recorded.                               |
| `signing.pending_approval`    | The signing request is held for approval.                            |
| `signing.resumed`             | An approved signing request continued to the cluster.                |
| `signing.rejected`            | An approver rejected the signing request.                            |
| `signing.failed`              | Signing failed or timed out.                                         |

Each payload carries the event type, the event ID, the workspace and the affected resource with its current state, so a consumer can act on it without a follow-up read.
