API Reference

Webhooks API

Receive signed Klarefi events, send test deliveries, and acknowledge handoff delivery

Klarefi delivers signed events to webhook endpoints registered in the dashboard. Use webhooks as integration signals, then read the current case or package when your system needs canonical state.

Webhook delivery flow

v1.webhook.test is emitted only by the test endpoint. Subscription events use the catalog names in the dashboard, such as v1.intake.submitted and v1.case.completed.

Event Shape

{
  "event_id": "evt_01J7W9S4TSQ0T4SH43JYB9W5R8",
  "delivery_id": "whd_01J7W9S52C2ZK1XFY2GM7Z7SAK",
  "event_type": "v1.case.completed",
  "semantic_event_type": "case.completed",
  "schema_version": "v1",
  "created_at": "2026-05-01T12:34:56.000Z",
  "occurred_at": "2026-05-01T12:34:50.000Z",
  "org_id": "org_abc123",
  "case_id": "case_abc123",
  "session_id": null,
  "external_case_id": "claim_12345",
  "external_applicant_id": "applicant_789",
  "external_customer_id": "customer_456",
  "idempotency_key": "process_claim_12345_doc_1",
  "trace_id": "trace_claim_12345",
  "data": {
    "case_status": "completed"
  }
}

Deliveries are at least once. Process duplicates idempotently by delivery_id.

Signature Verification

Each delivery includes:

X-Klarefi-Signature: t=1704067200,v1=abc123def456...

The signature is:

HMAC-SHA256(signing_secret, timestamp + "." + raw_body)

Use the raw request body before JSON parsing.

import { constructEvent, KlarefiWebhookSignatureError } from "@klarefi/node";

export async function POST(request: Request) {
  const rawBody = await request.text();

  try {
    const event = constructEvent(
      rawBody,
      request.headers.get("X-Klarefi-Signature"),
      process.env.KLAREFI_WEBHOOK_SECRET!,
    );

    if (event.event_type === "v1.case.completed") {
      // Read the case package and update your system of record.
    }

    return Response.json({ received: true });
  } catch (error) {
    if (error instanceof KlarefiWebhookSignatureError) {
      return new Response("Invalid signature", { status: 401 });
    }
    throw error;
  }
}

Test A Webhook Receiver

Required scope: webhooks:test

curl -X POST "$KLAREFI_API_BASE_URL/api/v1/webhooks/test" \
  -H "Authorization: Bearer $KLAREFI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "endpoint_url": "https://your-app.example.com/webhooks/klarefi",
    "signing_secret": "whsec_your_signing_secret"
  }'
{
  "success": true,
  "status_code": 200
}

Acknowledge A Delivery

Required scope: webhooks:acknowledge

curl -X POST "$KLAREFI_API_BASE_URL/api/v1/webhooks/deliveries/whd_123/ack" \
  -H "Authorization: Bearer $KLAREFI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "acknowledgement_id": "ack_claim_12345" }'
{
  "acknowledged": true,
  "already_acknowledged": false,
  "delivery_id": "whd_123",
  "case_id": "case_abc123",
  "handoff_state": "acknowledged"
}

Acknowledgement is useful when your system wants Klarefi to record that a decision-ready handoff has been received.

On this page