Webhooks API
Subscribe to real-time event notifications.
Overview
Webhooks push real-time event notifications to your external systems. Instead of polling the API, register a URL and Katura will POST event data to it when things happen.
Available webhook events
order.createdβ new order placedorder.updatedβ order status changedorder.cancelledβ order cancelledcustomer.createdβ new customer registeredproduct.createdβ new product addedproduct.updatedβ product modifiedinventory.lowβ stock level below threshold
Registering a webhook
- Go to Settings β Developer β Webhooks
- Click Add Webhook
- Enter the endpoint URL and select the events to subscribe to
- Save β Katura will begin sending events immediately
Webhook security
Each webhook includes a signature header for verification. Always validate the signature before processing webhook data to prevent spoofing.
Payload shape
POST https://your-app.example.com/hooks/katura
Content-Type: application/json
X-Katura-Event: order.paid
X-Katura-Delivery: dlv_01HX...
X-Katura-Timestamp: 1714152043
X-Katura-Signature: t=1714152043,v1=8a3c...
{
"event": "order.paid",
"data": {
"id": "ord_01HX...",
"number": "1042",
"total": "5184.00",
"currency": "USD",
"customer": { "id": "cus_01HX...", "email": "alice@example.com" },
"paidAt": "2026-04-26T18:40:43.123Z"
}
}Signature verification
Verify X-Katura-Signature using HMAC-SHA256 of {timestamp}.{rawBody}with your webhook secret. Reject anything older than 5 minutes to prevent replay.
// Node.js / TypeScript
import crypto from "node:crypto";
export function verifyKaturaSignature(
rawBody: string,
header: string,
secret: string,
): boolean {
const parts = Object.fromEntries(
header.split(",").map(kv => kv.split("="))
);
const timestamp = Number(parts.t);
if (!timestamp || Math.abs(Date.now() / 1000 - timestamp) > 300) return false;
const signed = `${timestamp}.${rawBody}`;
const expected = crypto
.createHmac("sha256", secret)
.update(signed)
.digest("hex");
return crypto.timingSafeEqual(
Buffer.from(expected, "hex"),
Buffer.from(parts.v1, "hex")
);
}Delivery & retries
Katura expects a 2xx response within 10 seconds. Anything else triggers an exponential-backoff retry: 1 min, 5 min, 30 min, 2 hr, 12 hr, then daily for 7 days. After that the delivery is marked failed and the receiving endpoint gets a summary email.
Replay any delivery from Settings β Developer β Webhooks β Deliveries. Each delivery shows headers, body, response status, response body, and timing.
Best practices
- Acknowledge fast, work later. Return 200 immediately, queue the heavy work.
- Idempotent handlers. Use
X-Katura-Deliveryas a dedup key β the same event will retry. - One secret per endpoint. Rotating one doesn't affect others.
- Don't trust event order.
order.paidcan arrive beforeorder.createdin rare network conditions; design for it.
