Webhooks
Events POST to your registered https endpoint as JSON:
| Event | When |
|---|---|
deposit.received | SAR arrives in your funding account |
order.executed | an order settles |
order.failed | execution fails (order recorded as failed) |
withdrawal.settled | a withdrawal completes or fails (failed = auto-refunded) |
Verifying signatures
Each delivery carries X-Sabika-Event and
X-Sabika-Signature: t=<unix>,v1=<hex> where
v1 = HMAC-SHA256("<t>.<raw body>", endpoint_secret).
import { createHmac, timingSafeEqual } from 'node:crypto';
function verifyWebhook(rawBody, signatureHeader, secret, toleranceS = 300) {
const m = signatureHeader.match(/^t=(\d+),v1=([0-9a-f]{64})$/);
if (!m) return false;
const [, t, v1] = m;
if (Math.abs(Date.now() / 1000 - Number(t)) > toleranceS) return false;
const expected = createHmac('sha256', secret).update(`${t}.${rawBody}`).digest('hex');
return timingSafeEqual(Buffer.from(v1), Buffer.from(expected));
}
Verify against the raw request body bytes — do not
re-serialize parsed JSON.
Delivery & retries
Respond with any 2xx within 10 seconds. Non-2xx, timeouts, and redirects are retried with exponential backoff (2n × 30s, capped) up to 10 attempts, then marked failed. Deliveries can arrive out of order — use the event payload's ids, not arrival order.