Docs Navigation
Current: Webhooks
Open all sections
Overview
Getting Started
Role Guides
Compliance & Trust
Developer Reference
More
Home / Documentation / API Webhooks
Webhook Reference
Webhook notifications let integrations react to lifecycle changes without polling.
Delivery Model
- At-least-once delivery (deduplicate with event IDs).
- Retry behavior with exponential backoff on non-2xx responses.
- Webhook signatures provided in
X-Fractal-Signature. - Consumers should acknowledge events quickly and process asynchronously.
Signature Verification
# Header provided with each delivery
X-Fractal-Signature: sha256=<hmac_hex>
# Node.js example
const crypto = require("crypto");
function verifyWebhook(payload, signature, secret) {
const expected = crypto
.createHmac("sha256", secret)
.update(payload, "utf8")
.digest("hex");
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from("sha256=" + expected),
);
}Event Catalog
| Event | Trigger |
|---|---|
offering.status.changed | An offering lifecycle status changed |
subscription.status.changed | A subscription status changed |
distribution.completed | A distribution payout completed |
investor.kyc.updated | Investor KYC status changed |
Payload Examples
offering.status.changed
{
"event": "offering.status.changed",
"timestamp": "2026-02-15T12:00:00Z",
"data": {
"offering_id": "off_abc123",
"previous_status": "pending_review",
"new_status": "open"
}
}subscription.status.changed
{
"event": "subscription.status.changed",
"timestamp": "2026-02-15T12:05:00Z",
"data": {
"subscription_id": "sub_xyz789",
"previous_status": "payment_pending",
"new_status": "paid"
}
}distribution.completed
{
"event": "distribution.completed",
"timestamp": "2026-02-15T12:08:00Z",
"data": {
"distribution_id": "dist_001",
"gross_amount": "10000.00",
"wht_deducted": "1000.00",
"net_amount": "9000.00"
}
}investor.kyc.updated
{
"event": "investor.kyc.updated",
"timestamp": "2026-02-15T12:12:00Z",
"data": {
"investor_id": "inv_def456",
"previous_status": "pending",
"new_status": "approved"
}
}
