Webhooks

BankLyra delivers real-time event notifications to your HTTPS endpoint. Use webhooks to react to new transactions, payment settlements, balance changes, and consent lifecycle events — without polling.

Registering a webhook endpoint

Register your HTTPS endpoint in the Dashboard → Webhooks panel. You can register multiple endpoints and filter each one to a specific set of event types. Each endpoint receives a signing secret for verification.

Webhook endpoints must return HTTP 200 within 10 seconds. BankLyra retries failed deliveries with exponential backoff for up to 24 hours (maximum 8 attempts). Endpoints returning non-2xx are considered failed.

Event types

EventTrigger
transaction.newNew transaction detected in the bank's API since last refresh
balance.updatedAccount balance has changed since last known value
consent.activatedUser completed SCA and consent is now active
consent.expiredConsent has passed its expiry date
consent.revokedConsent was revoked via the API or by the user at their bank
payment.authorisedUser approved the payment via SCA
payment.settledPayment confirmed as settled by the bank
payment.rejectedPayment was rejected by the bank (insufficient funds, security, etc.)

Event payload

transaction.new event
{
  "event": "transaction.new",
  "event_id": "evt_01HXP2K9QZRT7VN3",
  "created_at": "2025-11-14T10:22:01Z",
  "data": {
    "account_id": "acc_01HXNP3K7WQBFR2T",
    "transaction": {
      "id": "txn_01HXP2K9QZRT7VN4",
      "amount": -42.80,
      "currency": "GBP",
      "booking_date": "2025-11-14",
      "description": "DIRECT DEBIT NETFLIX",
      "category": "entertainment"
    }
  }
}

Verifying signatures

Every webhook includes a BankLyra-Signature header — an HMAC-SHA256 digest of the request body using your endpoint's signing secret. Always verify this before processing the payload.

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

function verifySignature(rawBody, signature, secret) {
  const expected = crypto
    .createHmac('sha256', secret)
    .update(rawBody)
    .digest('hex');
  return crypto.timingSafeEqual(
    Buffer.from(expected), Buffer.from(signature)
  );
}