Skip to content

Integration

Webhooks Integration

Register Lamba webhook endpoints from Console, get the signing secret, verify delivery headers, understand payload fields, and process retries safely.

Choose this when

Use this path when your product needs signed Lamba events for auth, membership, session, webhook, campaign, loyalty, notification, or audit workflows.

Webhook handlers should be small:

  1. read the raw request body
  2. verify the signature
  3. deduplicate by event ID
  4. persist the event or enqueue work
  5. return 2xx

Before you start

You need:

  • a public HTTPS endpoint under your control
  • raw-body access in your web framework
  • durable storage for processed event IDs
  • access to the selected Workspace, Project, and environment in the Lamba console

Get credentials from Console

Open the selected Project, then go to Integration > Webhooks.

Credentials and configuration values
ValueConsole sourceEnv varUsed for
Endpoint URLIntegration > Webhooks > Add endpointLAMBA_WEBHOOK_ENDPOINT_URLPublic HTTPS URL that receives `POST` deliveries
Subscribed eventsIntegration > Webhooks > Add endpoint or configured endpoint rowLAMBA_WEBHOOK_EVENTSLimits delivery to the event families your product handles
Signing secretSecretIntegration > Webhooks > Open securityLAMBA_WEBHOOK_SECRETHMAC verification for every delivery
Endpoint IDIntegration > Webhooks > Configured endpointsLAMBA_WEBHOOK_ENDPOINT_IDDelivery inspection, retry workflows, and endpoint-specific operations

Configure environment variables

LAMBA_WEBHOOK_SECRET=<signing-secret>
LAMBA_WEBHOOK_TOLERANCE_SECONDS=300

Store the secret in server-side secret storage. Rotate it from the console if it is exposed.

Make the first request

Register your endpoint from the console, then use Send sandbox on the configured endpoint row. The delivery is a POST to your URL.

POSTYour HTTPS receiver/api/lamba/webhooks
Auth
HMAC signature in Lamba delivery headers
Used for
Receives signed Lamba event facts

Minimal Next.js route:

import crypto from "node:crypto";
import { NextResponse } from "next/server";

export async function POST(request: Request) {
  const rawBody = await request.text();
  const signature = request.headers.get("x-lamba-signature") ?? "";
  const timestamp = request.headers.get("x-lamba-timestamp") ?? "";

  if (!verifySignature(rawBody, signature, timestamp, process.env.LAMBA_WEBHOOK_SECRET!)) {
    return NextResponse.json({ error: "invalid_signature" }, { status: 400 });
  }

  const event = JSON.parse(rawBody) as { id: string; type: string };
  await persistEventForAsyncProcessing(event.id, rawBody);

  return new Response(null, { status: 204 });
}

function verifySignature(rawBody: string, signature: string, timestamp: string, secret: string) {
  const expected = `v1=${crypto
    .createHmac("sha256", secret)
    .update(`${timestamp}.${rawBody}`)
    .digest("hex")}`;

  return crypto.timingSafeEqual(
    Buffer.from(expected, "utf8"),
    Buffer.from(signature, "utf8")
  );
}

async function persistEventForAsyncProcessing(_eventId: string, _rawBody: string) {
  // Store the event ID before doing side effects so retries stay idempotent.
}

Request fields

Delivery headers:

Request and response fields
FieldTypeRequiredMeaningNotes
X-Lamba-SignaturestringRequiredHMAC signature over `timestamp.rawBody`.Compare with constant-time equality.
X-Lamba-TimestampUnix timestamp or ISO timestampRequiredDelivery timestamp used for replay protection.Reject requests outside your tolerance window.
X-Lamba-EventstringRequiredEvent type, such as `user.created` or `campaign.sent`.-
X-Lamba-DeliverystringRequiredUnique delivery attempt identifier.Use the body `id` as the event idempotency key.

Event body:

{
  "id": "evt_...",
  "type": "user.created",
  "workspaceId": "wrk_...",
  "projectId": "prj_...",
  "environment": "test",
  "createdAt": "2026-05-31T12:00:00Z",
  "data": {
    "userId": "usr_...",
    "email": "customer@example.com"
  }
}
Request and response fields
FieldTypeRequiredMeaningNotes
idstringRequiredStable event ID.Store this value to deduplicate retries.
typestringRequiredEvent type that determines which handler should run.-
workspaceIdstringRequiredWorkspace where the event occurred.Use this instead of customer-facing tenant terminology.
projectIdstringRequiredProject runtime context for the event.-
environmenttest | prodRequiredEnvironment that produced the event.-
createdAtISO-8601 datetimeRequiredWhen Lamba recorded the event fact.-
dataobjectRequiredEvent-specific payload.Do not assume every event has the same nested fields.

Response fields

Your receiver controls the HTTP response:

Request and response fields
FieldTypeRequiredMeaningNotes
2xxHTTP statusRequiredAcknowledges durable receipt.Return only after signature verification and event persistence.
4xxHTTP statusOptionalPermanent receiver-side rejection.Use for invalid signature or malformed requests.
5xx or timeoutHTTP status / network failureOptionalTemporary receiver failure.Lamba retries failed deliveries with backoff.

Done when

Done when

  • The endpoint is registered under `Integration > Webhooks` for the selected environment.
  • Your receiver verifies `X-Lamba-Signature` against the raw body.
  • Replay protection rejects stale timestamps.
  • The event body `id` is stored before side effects run.
  • A sandbox delivery returns `2xx` and appears as successful in delivery logs.

Troubleshooting

SymptomLikely causeFix
Invalid signatureFramework parsed or reformatted the body before verificationVerify against the raw request body exactly as received
Repeated retriesHandler returns non-2xx, times out, or persists after side effectsPersist first, enqueue work, then return quickly
Duplicate downstream actionEvent ID is not used as idempotency keyStore body id and treat repeat deliveries as already processed
Missing eventsEndpoint subscription filters exclude the event typeReview Integration > Webhooks subscribed events
Sandbox events appear in production handlingEnvironment not checkedBranch on body environment and keep secrets separate
  • Webhook Signature Verification: /docs/reference/webhook-signatures
  • Webhook Events: /docs/reference/webhook-events
  • Webhook Deliveries: /docs/reference/webhook-deliveries
  • Incident Communication: /docs/reference/incident-comms