Platform
Receive real-time event notifications instead of polling the API.
When an event happens in Xeboki (subscription renewed, invoice paid, etc.), we immediately send an HTTP POST request to your registered endpoint. Your server responds with a 2xx status to acknowledge receipt.
Register
Add your HTTPS endpoint in Connected Apps
Receive
We POST signed JSON to your URL within seconds
Verify
Check the X-Xeboki-Signature header to confirm authenticity
subscription.createdA new subscription was activatedsubscription.updatedSubscription plan or status changedsubscription.canceledSubscription was canceledsubscription.renewedSubscription auto-renewed successfullysubscription.pausedSubscription billing was pausedsubscription.resumedPaused subscription was resumedinvoice.createdNew invoice was generatedinvoice.paidInvoice payment succeededinvoice.failedInvoice payment failedpayment.succeededPayment processed successfullypayment.refundedPayment was refundeduser.updatedProfile information changeduser.deletedAccount was permanently deletedEvery webhook delivery includes an X-Xeboki-Signature header. Use it to verify the payload came from Xeboki and was not tampered with.
const crypto = require('crypto')
function verifySignature(secret, rawBody, signatureHeader) {
const expected = 'sha256=' + crypto
.createHmac('sha256', secret)
.update(rawBody)
.digest('hex')
// Use timingSafeEqual to prevent timing attacks
return crypto.timingSafeEqual(
Buffer.from(expected),
Buffer.from(signatureHeader)
)
}
// In your Express handler:
app.post('/xeboki-events', express.raw({ type: 'application/json' }), (req, res) => {
const sig = req.headers['x-xeboki-signature']
if (!verifySignature(process.env.XEBOKI_WEBHOOK_SECRET, req.body, sig)) {
return res.status(400).send('Invalid signature')
}
const event = JSON.parse(req.body)
console.log('Event:', event.event, event.data)
res.json({ received: true })
})import hmac, hashlib
def verify_signature(secret: str, raw_body: bytes, signature_header: str) -> bool:
expected = 'sha256=' + hmac.new(
secret.encode(), raw_body, hashlib.sha256
).hexdigest()
return hmac.compare_digest(expected, signature_header)
# In your Flask handler:
@app.route('/xeboki-events', methods=['POST'])
def handle_webhook():
sig = request.headers.get('X-Xeboki-Signature', '')
if not verify_signature(os.environ['XEBOKI_WEBHOOK_SECRET'], request.data, sig):
return 'Invalid signature', 400
event = request.get_json(force=True)
print(f"Event: {event['event']}", event['data'])
return {'received': True}{
"id": "wh_a1b2c3d4e5f6",
"event": "invoice.paid",
"created_at": "2026-03-30T12:00:00Z",
"test": false,
"data": {
"invoice_id": "inv_xyz789",
"amount_cents": 2900,
"currency": "usd"
}
}If your endpoint returns a non-2xx response or times out (10s), we retry with exponential backoff:
After 5 consecutive failures the endpoint is automatically disabled. Re-enable it in Connected Apps.
Register your HTTPS endpoint in Connected Apps to start receiving events.