Webhooks
Voltage Webhooks give you real-time visibility and automation capabilities for your Lightning nodes and Voltage Infrastructure. With just a few configuration steps, you can subscribe to critical events from your infrastructure—ranging from invoice settlements and channel state changes to new block notifications and wallet unlock requests.
These webhooks are built to be reliable, secure, and developer-friendly. Each webhook includes rich metadata, automatic retry behavior, and support for custom event handling so your stack can respond immediately and intelligently to activity on your node.
Lightning Node Webhooks:
Custom Voltage hosted invoice webhook implementation:
Reach out to have the Voltage hosted invoice webhook activated for your team.
# Webhook Proxy Documentation
## Overview
The Webhook Proxy service allows you to receive real-time notifications from your LND nodes via webhooks. It supports multiple event types and provides reliable delivery with automatic retries.
## Webhook Payload
When an event occurs, the service will send a POST request to your configured webhook URL with the following payload structure:
```json
{
"node_id": "string", // The ID of the LND node that generated the event
"event_type": "string", // Type of event (see Event Types below)
"data": { // Event-specific data
...
},
"metadata": {
"timestamp": 1708387874, // Unix timestamp of when the event was sent
"attempt": 1, // Current delivery attempt number
"max_retries": 3, // Maximum number of retry attempts
"webhook_id": "string", // ID of your webhook configuration
"delivery_id": "string" // Unique ID for this delivery attempt
}
}
```
### HTTP Headers
Each webhook request includes the following headers:
```
Content-Type: application/json
X-Event-Type: <event_type>
X-Node-ID: <node_id>
X-Webhook-ID: <webhook_id>
X-Delivery-ID: <delivery_id>
X-Attempt: <current_attempt>
X-Max-Retries: <max_retries>
```
## Event Types
The service supports the following event types:
### 1. Invoice Events (`event_type: "invoice"`)
Triggered when an invoice is created, settled, or canceled.
```json
{
"event_type": "invoice",
"data": {
"payment_hash": "string",
"value_sat": "integer",
"settled": "boolean",
"creation_date": "integer",
"settle_date": "integer",
"payment_request": "string",
"memo": "string",
"state": "string" // "OPEN", "SETTLED", or "CANCELED"
}
}
```
### 2. Channel Events (`event_type: "channel"`)
Triggered for channel-related events (open, close, pending, active, inactive).
```json
{
"event_type": "channel",
"data": {
"channel_point": "string",
"capacity": "integer",
"remote_pubkey": "string",
"channel_id": "integer",
"event": "string", // "OPEN", "CLOSED", "ACTIVE", "INACTIVE", "PENDING"
"close_type": "string" // Only present for "CLOSED" events
}
}
```
### 3. Block Events (`event_type: "block"`)
Triggered when a new block is detected.
```json
{
"event_type": "block",
"data": {
"block_hash": "string",
"block_height": "integer",
"timestamp": "integer"
}
}
```
### 4. Transaction Events (`event_type: "transaction"`)
Triggered when a new on-chain transaction is detected.
```json
{
"event_type": "transaction",
"data": {
"tx_hash": "string",
"amount": "integer",
"num_confirmations": "integer",
"block_hash": "string",
"block_height": "integer",
"timestamp": "integer",
"is_outbound": "boolean"
}
}
```
### 5. Peer Events (`event_type: "peer"`)
Triggered when peers connect or disconnect.
```json
{
"event_type": "peer",
"data": {
"peer_pubkey": "string",
"address": "string",
"action": "string" // "CONNECTED" or "DISCONNECTED"
}
}
```
### 6. Chain Events (`event_type: "chain"`)
Triggered for blockchain-related events.
```json
{
"event_type": "chain",
"data": {
"block_hash": "string",
"block_height": "integer",
"event": "string" // "REORG" or "CONFIRMED"
}
}
```
## Delivery Behavior
- The service will attempt to deliver webhooks immediately when events occur
- If delivery fails, it will retry with exponential backoff
- Default retry configuration: 3 attempts with 5-second initial delay
- Successful delivery requires a 2xx response (200, 201, or 202)
- Any non-2xx response is considered a failure and will trigger a retry
- Each retry includes the current attempt number in both the payload and headers
## Best Practices
1. **Idempotency**: Always use the `delivery_id` to deduplicate webhook deliveries
2. **Quick Response**: Your webhook endpoint should respond quickly (< 5 seconds)
3. **Async Processing**: If you need to do heavy processing, accept the webhook quickly and process asynchronously
4. **Verification**: Store your webhook configurations securely and verify the webhook ID in the headers
5. **Logging**: Use the delivery ID for correlation in your logs
## Error Handling
Your webhook endpoint should handle errors gracefully:
1. Return 2xx status code if you successfully received and queued/processed the webhook
2. Return 429 if you need the proxy to back off temporarily
3. Return 4xx for validation errors or if you explicitly don't want a retry
4. Return 5xx if you want the proxy to retry the deliveryCustom self-serve invoice webhook implementation:
Here is an example that YOU can fork and refactor, or deploy as a simple service independently: https://replit.com/@voltage-cloud/lnd-invoices-webhook-pro
Infrastructure Webhooks
Voltage also provides webhook support for monitoring your node's lifecycle, configuration, and operational status — allowing you to build automated responses for events like node restarts, updates, or initialization.
These webhooks are especially useful for:
- Automatically unlocking your node after restart
- Alerting when a new version of LND or Volt is available
- Detecting when your node stops or enters maintenance mode
Each infrastructure webhook includes a standard payload structure and is delivered with the Voltage-Secret header for verification.
Event Payload Structure:
{
"type": "string", // "status", "update", or "error"
"details": { // Event-specific details
...
},
"api": "string" // Your node's endpoint (e.g. yournode.m.voltageapp.io)
}
Supported Infrastructure Event Types
1. Status Events type: "status"
These events indicate your node’s current state in the startup lifecycle or runtime.
waiting_unlock
Triggered when your node restarts and is waiting to be unlocked.
{
"type": "status",
"details": {
"status": "waiting_unlock"
},
"api": "yournode.m.voltageapp.io"
}waiting_init
Triggered when your node is brand new and awaiting initialization.
{
"type": "status",
"details": {
"status": "waiting_init"
},
"api": "yournode.m.voltageapp.io"
}stopped
Triggered when your node is gracefully or unexpectedly stopped.
{
"type": "status",
"details": {
"status": "stopped"
},
"api": "yournode.m.voltageapp.io"
}2. Update Events type: "update"
These events inform you when a new version of LND or the Voltage agent (volt) is available for your node.
update_available
{
"type": "update",
"details": {
"update_available": "true",
"lnd_version": "0.17.0-beta",
"volt_version": "v0.4.0"
},
"api": "yournode.m.voltageapp.io"
}Verifying Infra Webhooks
When handling infrastructure webhooks, your server should:
- Verify the Voltage-Secret header matches your stored secret.
- Validate the api field to ensure it matches your expected node.
- Check the type and details to confirm event purpose.
- Take appropriate action based on event type (e.g., unlock the wallet, notify admin, etc).
Example: Automatically Unlocking Your Node
You can use Voltage Webhooks to automatically unlock your node after it restarts. This is especially useful for automation or unattended node restarts.
Step 1: Set Your Webhook Endpoint
To begin, configure your webhook endpoint in the Voltage Dashboard:
- Navigate to your node in the Voltage Dashboard.
- Click Monitoring in the sidebar.
- Select Webhooks & Watchtowers.
- Find the Webhook URL field and paste in the endpoint where Voltage should send webhook events.
- Make note of your Webhook Secret – this will be required to verify incoming requests.
Step 2: Handle the waiting_unlock Event
Once your webhook is set, you’ll need to handle the waiting_unlock event to trigger the unlock.
Example Payload:
{
"type": "status",
"details": {
"status": "waiting_unlock"
},
"api": "yournode.m.voltageapp.io"
}Your webhook handler should:
- Verify the Voltage-Secret header matches your stored secret.
- Validate the api field to ensure the event came from the expected node.
- Check the type field is status.
- Check the details.status field is waiting_unlock.
If all checks pass, proceed to unlock the wallet.
Step 3: Unlock the Node via LND API
To unlock the wallet, send a POST request to your node's /v1/unlockwallet endpoint. This follows the LND API documentation.
The payload must contain:
- wallet_password: Your wallet password, base64-encoded
- stateless_init: Set to true
Example:
curl -X POST https://yournode.m.voltageapp.io:8080/v1/unlockwallet \
-d '{ "wallet_password": "cGFzc3dvcmQK", "stateless_init": true }'Replace the wallet_password value with your base64-encoded password.
Security Reminder
- Store your Webhook Secret and wallet password securely using a password manager or environment variables.
- Never hard-code credentials into your source code.
With this setup in place, your node will automatically unlock itself every time it restarts – fully automated and ready to route again.