Webhook Notifications¶
Webhooks enable programmatic integration with your systems, sending HTTP POST requests when events occur.
Setup¶
Adding a Webhook¶
- Go to Settings → Notifications → Add Channel
- Select Webhook
- Enter your webhook URL
- Click Save
- Copy the HMAC secret for signature verification
Webhook URL Requirements¶
- HTTPS is recommended
- Must return 2xx status code within 30 seconds
- Should be publicly accessible
Local / HTTP development
In some self-hosted or development setups, you may be able to use plain HTTP depending on server configuration. For production, use HTTPS.
Webhook Payload¶
Request Format¶
POST /your-webhook-endpoint HTTP/1.1
Host: your-server.com
Content-Type: application/json
X-BtcWatch-Signature: sha256=abc123...
X-BtcWatch-Timestamp: 1705312496
{
"event_type": "transaction.deposit",
"severity": "info",
"title": "Deposit detected",
"message": "A deposit was detected in the mempool",
"user_id": 123,
"wallet_id": 456,
"event_data": {},
"timestamp": "2024-01-15T12:34:56Z"
}
Common Payload Fields¶
| Field | Type | Description |
|---|---|---|
event_type |
string | Event type |
timestamp |
ISO 8601 | When event occurred |
severity |
string | Severity (e.g. info, warning, critical) |
title |
string | Short human-readable title |
message |
string | Human-readable message |
user_id |
number | User ID |
wallet_id |
number | Wallet ID (may be null) |
event_data |
object | Event-specific structured payload |
Event-Specific Fields¶
See Event Types for fields specific to each event.
HMAC Signature Verification¶
Webhook requests may be signed using HMAC-SHA256. If a secret is configured for the channel, verify signatures to ensure requests are from Vigil.
Signature Header¶
Timestamp Header¶
Verification Algorithm¶
import hmac
import hashlib
def verify_signature(timestamp: str, payload: bytes, signature: str, secret: str) -> bool:
received_sig = signature.replace("sha256=", "")
mac = hmac.new(secret.encode(), digestmod=hashlib.sha256)
mac.update(timestamp.encode())
mac.update(b".")
mac.update(payload)
expected_sig = mac.hexdigest()
# Constant-time comparison
return hmac.compare_digest(received_sig, expected_sig)
Example: Node.js Verification¶
const crypto = require('crypto');
function verifySignature(timestamp, payload, signature, secret) {
const receivedSig = signature.replace('sha256=', '');
const expectedSig = crypto
.createHmac('sha256', secret)
.update(`${timestamp}.`)
.update(payload)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(receivedSig),
Buffer.from(expectedSig)
);
}
Example: Python Verification¶
import hmac
import hashlib
def verify_webhook(request, secret):
signature = request.headers.get('X-BtcWatch-Signature')
timestamp = request.headers.get('X-BtcWatch-Timestamp')
payload = request.get_data()
if not signature:
return False
return verify_signature(timestamp, payload, signature, secret)
Replay Prevention¶
Use the timestamp header to prevent replay attacks:
import time
def is_request_fresh(timestamp_header: str, tolerance_seconds: int = 300) -> bool:
request_time = int(timestamp_header)
current_time = int(time.time())
return abs(current_time - request_time) < tolerance_seconds
Retry Policy¶
If your endpoint returns an error or times out:
| Attempt | Delay |
|---|---|
| 1 | Immediate |
| 2 | 1 minute |
| 3 | 5 minutes |
| 4 | 30 minutes |
| 5 | 2 hours |
After repeated failures, the channel may be marked as failing.
Response Requirements¶
Your endpoint must:
- Return HTTP 2xx status code
- Respond within 30 seconds
- Accept application/json content type
Recommended Response¶
Webhook Management¶
Viewing Delivery History¶
- Go to Settings → Notifications
- Click on your webhook channel
- View Delivery History
May show:
- Recent delivery attempts
- Response codes
- Failures and retries
Regenerating Secret¶
If your secret is compromised:
- Go to webhook settings
- Click Regenerate Secret
- Update your server with new secret
- Old secret is invalidated
Pausing a Webhook¶
Temporarily disable without deleting:
- Toggle the webhook off
- No webhooks will be sent
- Toggle back on to resume
Testing Webhooks¶
Test Endpoint¶
Use a service like webhook.site for testing:
- Go to webhook.site
- Copy your unique URL
- Add as webhook in Vigil
- Click the Test button
- View the test payload on webhook.site
Local Development¶
For local testing, use ngrok or similar:
Security Best Practices¶
- Always verify HMAC signatures
- Use HTTPS only
- Check timestamp freshness
- Store secret securely (environment variable)
- Log webhook deliveries for debugging
- Set up monitoring for webhook failures
Next: Nostr Notifications →