Agent skill

Lago Webhooks Skill

Receive and verify Lago webhooks in HMAC mode. Use when setting up Lago webhook handlers, debugging X-Lago-Signature verification, or handling usage billing events like invoice.created, subscription.started, or wallet.depleted_ongoing_balance.

Install this skill

npx skills add hookdeck/webhook-skills --skill lago-webhooks


When to Use This Skill

  • How do I receive Lago webhooks?
  • How do I verify the X-Lago-Signature header?
  • Why is my Lago webhook signature verification failing?
  • How do I handle invoice.created, subscription.terminated, or customer.created events?

Scope: HMAC mode only (not the JWT default)

Lago lets you pick a signature algorithm when you create a webhook endpoint: hmac or jwt. Lago's default is jwt (an RS256 JWT checked with the public key from /api/v1/webhooks/json_public_key). This skill covers hmac only. Choose HMAC when you create the endpoint (dashboard: Developers > Webhooks > Add an endpoint, or "signature_algo": "hmac" in POST /api/v1/webhook_endpoints). Every delivery carries X-Lago-Signature-Algorithm; the examples reject anything other than hmac.

Verification (core)

X-Lago-Signature is the base64 HMAC-SHA256 of the raw request body, keyed with your organization's HMAC Signature Token (Developers > Webhooks). There is no timestamp in the signed content. Lago has no official webhook-verification helper for HMAC, so verify manually.

const crypto = require('crypto');

function verifyLagoSignature(rawBody, signatureHeader, secret) {
  if (!signatureHeader || !secret) return false;
  const expected = crypto.createHmac('sha256', secret).update(rawBody).digest('base64');
  const a = Buffer.from(signatureHeader);
  const b = Buffer.from(expected);
  return a.length === b.length && crypto.timingSafeEqual(a, b);
}

Read the body as raw bytes (express.raw({ type: '*/*' }) so any content type verifies); never JSON.parse before verifying.

For complete handlers with tests, see examples/express/, examples/nextjs/, examples/fastapi/.

Payload and Headers

{ "webhook_type": "invoice.created", "object_type": "invoice", "organization_id": "...", "invoice": { } }

The object is under the key named by object_type. Headers: X-Lago-Signature, X-Lago-Signature-Algorithm (hmac), X-Lago-Unique-Key (idempotency key, process each key once).

Common Event Types

Dispatch on webhook_type:

EventDescription
invoice.createdInvoice finalized
invoice.payment_status_updatedPayment status of an invoice changed
subscription.startedSubscription started
subscription.terminatedSubscription terminated
customer.createdCustomer created
wallet.depleted_ongoing_balancePrepaid wallet ongoing balance is 0 or negative

For the full event list, see references/overview.md and the Lago webhook messages reference.

Environment Variables

LAGO_HMAC_KEY=your_organization_hmac_signature_token

This is the organization-wide HMAC Signature Token, not your Lago API key.

Local Development

npx hookdeck-cli listen 3000 lago --path /webhooks/lago

Reference Materials


Repository

hookdeck/webhook-skills

v0.1.0 · MIT · Updated Nov 5, 2026

View on GitHub →