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

# Webhooks

> Subscribe to events and build reliable delivery handling.

Webhooks let Ledger push real-time events to your HTTPS endpoint instead of requiring you to poll.

## Create a webhook

```bash theme={null}
curl -X POST https://api.ledger.so/v1/webhooks \
  -H "Authorization: Bearer $LEDGER_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: create-webhook-1" \
  -d '{
    "url": "https://example.com/ledger/webhooks",
    "events": ["transaction.created", "transaction.completed", "customer.updated"]
  }'
```

Use `["*"]` to subscribe to all events, or specify individual event types.

## Events

### Customer events

| Event              | When it fires                                        |
| ------------------ | ---------------------------------------------------- |
| `customer.created` | New customer created via the API                     |
| `customer.updated` | Customer status, KYC status, or capabilities changed |

### Transaction events

| Event                   | When it fires                                                                                               |
| ----------------------- | ----------------------------------------------------------------------------------------------------------- |
| `transaction.created`   | New transaction recorded — transfer initiated or crypto deposited to a wallet                               |
| `transaction.updated`   | Transaction status changed (e.g. `funds_received` → `payment_submitted`)                                    |
| `transaction.completed` | Transaction reached a terminal state: `completed`, `payment_processed`, `failed`, `returned`, or `refunded` |

### Wallet events

| Event            | When it fires             |
| ---------------- | ------------------------- |
| `wallet.created` | Crypto wallet provisioned |
| `wallet.updated` | Wallet status changed     |

### Virtual account events

| Event                     | When it fires                                    |
| ------------------------- | ------------------------------------------------ |
| `virtual_account.created` | Virtual account opened with deposit instructions |
| `virtual_account.updated` | Virtual account status changed                   |

### Counterparty events

| Event                  | When it fires                       |
| ---------------------- | ----------------------------------- |
| `counterparty.created` | Payout account added for a customer |

### Other

| Event          | When it fires                                       |
| -------------- | --------------------------------------------------- |
| `webhook.test` | Manually triggered via `POST /v1/webhooks/:id/test` |

## Event payload

Every event is delivered as a `POST` request with this body:

```json theme={null}
{
  "id": "evt_...",
  "type": "transaction.completed",
  "createdAt": 1710000000000,
  "data": {
    "id": "txn_...",
    "customerId": "cus_...",
    "type": "transfer",
    "status": "payment_processed",
    "amount": "5.0",
    "sourceCurrency": "usdc",
    "destinationCurrency": "gbp",
    "payoutAccountId": "pa_...",
    "finalAmount": "3.38",
    "exchangeFee": "0.0",
    "createdAt": 1710000000000,
    "updatedAt": 1710000100000
  }
}
```

The `data` object matches the same shape as the corresponding `GET` endpoint response.

## Test your webhook

```bash theme={null}
curl -X POST https://api.ledger.so/v1/webhooks/whk_.../test \
  -H "Authorization: Bearer $LEDGER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"data": {"message": "hello"}}'
```

## Retry policy

If your endpoint returns a non-2xx status code, Ledger retries with exponential backoff up to 10 attempts. View delivery history via `GET /v1/webhooks/:id/deliveries`.

## Next steps

* [Webhook Overview](/webhooks/overview) — delivery headers
* [Signature Verification](/webhooks/signature-verification) — verify events came from Ledger
