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

# Webhooks

> Receive signed webhook events from Brale when transfers and payments complete.

## Brale webhooks

Brale webhooks let your application receive real-time notifications when important events happen in Brale.

Instead of polling Brale APIs to check whether a transfer or payment has completed, you can register an HTTPS endpoint and Brale will `POST` a signed event to your application as soon as the event occurs.

Use webhooks to:

* Update your internal ledger when a transfer completes
* Notify your users when money movement settles
* Reconcile completed transfers or payments
* Prompt customers to upload KYB documents when verification review requires them
* Trigger downstream workflows without polling
* Build real-time dashboards for operations and treasury teams

## How webhooks work

At a high level:

1. You create a webhook subscription for your Brale account.
2. Brale returns a `sharedSecret` one time.
3. You store the `sharedSecret` securely.
4. When a subscribed event occurs, Brale sends an HTTPS `POST` to your endpoint.
5. Your application verifies the HMAC signature using the exact raw request body.
6. Your application processes the event idempotently.
7. Your endpoint returns a `2xx` response to acknowledge delivery.

```
Brale transfer completes
        ↓
Brale builds event payload
        ↓
Brale signs raw JSON body with your shared secret
        ↓
Brale POSTs the event to your webhook URL
        ↓
Your app verifies, deduplicates, and updates state
```

## Supported events

Use the event type discovery endpoint to see currently available events:

```
GET /accounts/{account_id}/webhooks/event_types
```

Current supported events:

| Event type                                | When it fires                             | Recommended use                                                                                                                                                                                                 |
| ----------------------------------------- | ----------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `transfer.created`                        | A transfer is created                     | Record transfer intents and surface in-flight state to customers                                                                                                                                                |
| `transfer.completed`                      | A transfer reaches `complete` status      | Replace polling transfer status; update ledgers, balances, and customer-facing status                                                                                                                           |
| `transfer.canceled`                       | A transfer is canceled                    | Reverse provisional ledger entries and notify customers of cancellations                                                                                                                                        |
| `transfer.failed`                         | A transfer reaches `failed` status        | React to permanent transfer failures (e.g., ACH returns); inspect `data.failure` for details                                                                                                                    |
| `payment.completed`                       | A payment reaches `complete` status       | React to completed payment events, including supported fiat payment flows                                                                                                                                       |
| `account.verification.documents_required` | KYB review requires one or more documents | Notify customers to upload documents; see [Stage a Verification Document](/api-reference/brale/stage-verification-document) and [Link Verification Documents](/api-reference/brale/link-verification-documents) |
| `account.verification.completed`          | Account verification passes               | Enable downstream flows when account `status` becomes `complete`                                                                                                                                                |

Use `transfer.completed` when your integration is tracking Brale Transfer objects and wants to know when a transfer has completed.

## Requirements

Your webhook endpoint must:

* Be publicly reachable over HTTPS
* Accept `POST` requests
* Accept `Content-Type: application/json`
* Read the raw request body before parsing JSON
* Verify the `x-request-signature-sha-256` header
* Return a `2xx` response quickly
* Deduplicate events by event `id` and/or `idempotency-key`

## Local development

For local development, expose your local server with a tool like ngrok or Cloudflare Tunnel.

Example local tunnel:

```bash theme={null}
ngrok http 4000
```

If ngrok gives you:

```
https://example.ngrok-free.app -> http://localhost:4000
```

your webhook URL might be:

```
https://example.ngrok-free.app/webhooks/brale
```
