Skip to main content

Webhooks

Webhooks deliver application, decision, invitation, screening, fraud and operational events to your HTTPS endpoint.

Create an endpoint

Use Client Admin Portal → Developers or the entitled developer API. Choose only events your service handles. The signing secret is shown once.

Common events:

EventWhen it fires
application.createdApplication and invitation committed
application.submittedApplicant finished the permitted journey
application.decidedFinal approve/reject decision committed
application.review_requiredPolicy or signal opened human work
application.recovery_requestedApplicant selected an approved alternative collection route
application.recovery_completedOperator closed the recovery request as completed
application.recovery_declinedOperator closed the recovery request as declined
invitation.sentDelivery provider accepted the message
screening.match_detectedA screening candidate needs disposition
fraud.alert_createdTransaction/account policy opened an alert

The endpoint catalogue shown in your tenant is authoritative.

Verify before parsing

Read the exact raw request bytes. Compute HMAC-SHA256 over the documented timestamp/body envelope with the endpoint secret, then compare signatures in constant time.

import { createHmac, timingSafeEqual } from "node:crypto";

function verifyAssayraWebhook(
rawBody: Buffer,
timestamp: string,
receivedSignature: string,
secret: string,
) {
const ageSeconds = Math.abs(Date.now() / 1000 - Number(timestamp));
if (!Number.isFinite(ageSeconds) || ageSeconds > 300) return false;

const expected = createHmac("sha256", secret)
.update(`${timestamp}.`)
.update(rawBody)
.digest("hex");
const supplied = Buffer.from(receivedSignature, "hex");
const computed = Buffer.from(expected, "hex");
return (
supplied.length === computed.length && timingSafeEqual(supplied, computed)
);
}

Use the exact header names displayed by the Developer Hub/test-delivery record. Keep raw-body middleware ahead of JSON parsing.

Acknowledge quickly

  1. Verify signature and timestamp.
  2. Deduplicate the event/delivery ID.
  3. Persist the event durably.
  4. Return a 2xx response.
  5. Process asynchronously and reconcile state through the API.

Do not hold the request open while provisioning an account or calling slow downstream systems.

Retries and rotation

Non-2xx delivery is retried with bounded backoff. Inspect attempts and response status in the delivery ledger. During secret rotation, accept the predecessor and successor only for the documented overlap, then remove the predecessor.

Never disable signature verification to fix a delivery problem.