API documentation

Verify webhook signatures and handle retries

Authenticate the exact body, check the timestamp, deduplicate event IDs, and retrieve result details with your API key.

Updated

Receiver
Public HTTPS

Register an endpoint your application controls.

Verify
Raw body first

Verify the signature before parsing the payload.

Deduplicate
Event ID

Store processed IDs before acknowledging.

Register a public HTTPS receiver

POST /api/v1/webhooks registers a destination and returns its signing secret once. Store that secret in server configuration. Destinations must use public HTTPS on port 443; private, local, reserved, and redirected destinations are rejected. Do not include a credential in the destination URL.

screening.completed events contain an event ID, environment, screening ID, status, and creation time. They omit the submitted subject. Fetch the authorized result separately if your handler needs it. Webhook delivery history and retries are available in the dashboard.

Verify before parsing or acting

Read the raw request body without reformatting JSON. Webhook-Id, Webhook-Timestamp, and Webhook-Signature authenticate the string formed from ID, timestamp, and exact body with periods between them. The signature header uses v1= followed by the SHA-256 HMAC in hexadecimal.

The client helper uses a five-minute timestamp tolerance and constant-time signature comparison. After verification, persist the event ID and your intended work in one transaction before acknowledging it. Duplicate deliveries should not create duplicate business actions. A changed delivery timestamp does not make a repeated event new.

Verify before parsing or acting
import { verifyWebhook } from '@sanctionskit/client';

const rawBody = await request.text();
const valid = verifyWebhook(
  process.env.SANCTIONSKIT_WEBHOOK_SECRET!,
  request.headers.get('Webhook-Id') ?? '',
  request.headers.get('Webhook-Timestamp') ?? '',
  rawBody,
  request.headers.get('Webhook-Signature') ?? ''
);
if (!valid) return new Response('Invalid signature', { status: 400 });
// Persist the event and durable work before returning 2xx.

KEEP BUILDING

Where to go next