Webhooks
Receive real-time notifications when events occur.
Overview
Configure webhook endpoints to receive real-time POST notifications when events occur in your account.
Events
| Event | Description |
|---|---|
DEPOSIT_ASSET_SUCCESS | A deposit was completed successfully. |
PAYOUT_SUCCESSFUL | A PIX payout was sent successfully. |
PAYOUT_FAILED | A PIX payout failed. |
Payload
Every webhook delivery sends a JSON body with the following structure:
{
"event": "PAYOUT_SUCCESSFUL",
"data": { ... }
}Headers
Each request includes these headers for verification:
| Header | Description |
|---|---|
X-Hodle-Signature | HMAC signature of the payload using your webhook secret. |
X-Hodle-Timestamp | Unix timestamp (seconds) when the request was sent. |
Plus any custom headers you configured on the webhook.
Verifying Signatures
Use the X-Hodle-Signature and X-Hodle-Timestamp headers to verify that the request came from Hodle.
import { createHmac } from 'crypto'
const verifyWebhook = (payload: string, signature: string, timestamp: string, secret: string) => {
const expected = createHmac('sha256', secret)
.update(`${timestamp}.${payload}`)
.digest('hex')
return expected === signature
}Retry Policy
Webhook deliveries are attempted once. A response with a 2xx status code is considered successful. Non-2xx responses are logged as failures.
PAYOUT_SUCCESSFUL
Sent when a PIX payout completes successfully after a Lightning invoice is paid.
{
"event": "PAYOUT_SUCCESSFUL",
"data": {
"success": true,
"invoice": "lnbc32310n1p5u2g2qsp5xq6j2rhspx7es5c0dymwrn2wcam6ay2vpgft65njm9pe6te93fgqpp57yym5t9vqw85a8zszx2e59xhr69yum0dd9udz26vgzgptwtpfplshp5uwcvgs5clswpfxhm7nyfjmaeysn6us0yvjdexn9yjkv3k7zjhp2sxq9z0rgqcqpnrzjqvmhlzgnvate6rxlc2pnhser58gp298w5sx53n8gd5c78xpz8cxtxrj7rvqqgfqqqqqqqqqqqqqq05qqyg9qxpqysgqdn0n0h52k8wv5mvsy5lm4ew075u24g2nr6ys7sn5276me8583arkyahkv25d08ngvwx0cwdre3eg6jtjpus4j7xs0gznctwzmtjk20qql2p832",
"valueInSatoshis": 276190,
"pixKey": "13d3109f-3a1e-4c56-b76d-d2db7213b9f2",
"valueInBrl": "1000.00",
"fee": "170.00",
"quote": {
"brlAmount": "1000.00",
"btcAmount": 0.0027619041618037344,
"satoshis": 276190,
"btcToBrlRate": 362069.04418686405
}
}
}Fields
| Field | Type | Description |
|---|---|---|
success | boolean | Whether the payout was successful. |
invoice | string | The Lightning invoice that was paid. |
valueInSatoshis | number | Amount received in satoshis. |
pixKey | string | The PIX key where BRL was sent. |
valueInBrl | string | Value in BRL. |
fee | string | Fee charged in BRL. |
quote.brlAmount | string | BRL amount quoted. |
quote.btcAmount | number | BTC amount. |
quote.satoshis | number | Amount in satoshis. |
quote.btcToBrlRate | number | BTC to BRL exchange rate at the time. |
PAYOUT_FAILED
Sent when a PIX payout fails.
{
"event": "PAYOUT_FAILED",
"data": {
"success": false,
"invoice": "lnbc10u1pj...",
"valueInSatoshis": 2450,
"pixKey": "user@email.com",
"valueInBrl": "10.00",
"fee": "0.20",
"error": "PIX key not found"
}
}DEPOSIT_ASSET_SUCCESS
Sent when a deposit completes successfully.
{
"event": "DEPOSIT_ASSET_SUCCESS",
"data": {
"success": true,
"value": 5000,
"asset": "LIGHTNING",
"fee": 100,
"fxRateAtTx": 362069.04
}
}