Skip to main content

Webhooks guide

Webhooks notify your integration when acts are created, duplicated, or change status. They also request refreshed values from your external data source.

Register a listener​

Create one registration for each event you need, using an HTTPS target. Use KREBIT_API and ACCESS_TOKEN from the quickstart:

curl --fail-with-body --silent --show-error --request POST \
"${KREBIT_API}/webhooks" \
--header "Authorization: Bearer ${ACCESS_TOKEN}" \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--data '{"event":"act.duplicated","target":"https://yourapp.example.com/webhooks/krebit"}'

Store the returned registration ID and secret securely. Use the API reference to create, list, inspect, or delete registrations.

Event catalog​

Each delivery contains an id, an event name, and an event-specific data object.

EventPayloadWhen it fires
act.createddata.actA new act is created.
act.status_changeddata.actAn act changes status, including moves between attestation steps.
act.duplicateddata.act and data.source_act_uuidAn act and its attachments have been copied into a new draft.
act.fetch_datadata.request_id, data.requested_at, data.expires_at, data.act, data.fieldsA user requests fresh data for a selection that includes external fields.

Duplication does not emit act.created or fetch fresh data. Subscribe to both creation and duplication if you need to track all new acts. For a duplicate, use data.act.uuid as the new act's identity and data.source_act_uuid to link it to the original.

Act objects include a saved case_type, or null when unclassified. See case-type metadata and filters.

Verify signatures​

Validate X-Signature against the raw request body before processing an event. X-Client-Id identifies the OAuth client associated with the registration. Use the secret for that registration.

import crypto from 'node:crypto';

function verifySignature(rawBody: Buffer, signature: string | undefined, secret: string): boolean {
if (!signature || !/^[a-f0-9]{64}$/i.test(signature)) {
return false;
}

const expected = crypto.createHmac('sha256', secret).update(rawBody).digest();
const received = Buffer.from(signature, 'hex');

return crypto.timingSafeEqual(expected, received);
}

Reject missing or malformed signatures. Preserve the raw body in your HTTP framework; reserializing parsed JSON can change the bytes and invalidate the signature.

Handle external data requests​

For act.fetch_data, acknowledging the webhook only confirms delivery. Return values or errors through the act data API with fetch_request_id set to data.request_id before data.expires_at. Process only selected fields where external_data_field is true; Krebit handles built-in provider fields.

Follow Return requested external data for complete single and bulk update examples, failures, retries, and 409 conflicts.

Reliability and troubleshooting​

  • Verify the event and durably record or enqueue it before returning 2xx. Process external calls asynchronously.
  • Deduplicate deliveries using the event id. For fetch results, also track request_id and field IDs so retries resume unfinished work.
  • Do not assume events arrive in order. Reconcile ordinary act state through the API after an outage.
  • If signature verification fails, check the registration secret, header, and raw body handling.
  • If deliveries stop, check the registration's active state, target reachability, and HTTP responses. Check the expiry deadline for fetch requests.
  • Keep tokens, secrets, contact information, and field values out of routine logs.