Webhook Events

CBrilliance can push signed events to Laskad via POST requests to the inbound webhook endpoint. Laskad verifies every request with HMAC-SHA256 and responds with 200 OK on success.

POSThttps://api.laskad.app/webhooks/cbrilliance

Signature Verification

Sign the raw request body with HMAC-SHA256 using the shared webhook secret. Pass the hex digest in the x-laskad-signature header.

// Node.js example
const crypto = require('crypto');

const signature = crypto
  .createHmac('sha256', WEBHOOK_SECRET)
  .update(rawBodyBuffer)  // Buffer, not string
  .digest('hex');

// Include as request header:
// x-laskad-signature: <signature>

Requests with a missing or non-matching signature are rejected with 401 Unauthorized. Laskad uses crypto.timingSafeEqual to prevent timing attacks.


Event Types

EVENTwithdrawal.completed

Sent by CBrilliance once a withdrawal has been transferred to the Laskad virtual account. Upon receipt, Laskad re-credits the group's escrow balance and sends a WhatsApp confirmation to the group.

Payload

{
  "type": "withdrawal.completed",
  "data": {
    "reference": "LSK-WD-1717228800000",
    "group_id": "cbr_abc123",
    "amount": 105000,
    "currency": "NGN",
    "timestamp": "2025-07-01T11:30:00Z"
  }
}
EVENTpayment.confirmed

Informational event sent by CBrilliance to acknowledge receipt of a Laskad settlement transfer. Laskad has already recorded the investment as ACTIVE after the Lint transfer succeeded — this event is for auditing only.

Payload

{
  "type": "payment.confirmed",
  "data": {
    "reference": "LSK-STL-1717228800000",
    "group_id": "cbr_abc123",
    "amount": 100000,
    "currency": "NGN",
    "timestamp": "2025-06-01T09:15:00Z"
  }
}

Expected Response

Laskad always responds with 200 OK. CBrilliance's retry logic should only trigger on non-2xx responses.

HTTP/1.1 200 OK
Content-Type: application/json

{ "received": true }