Webhooks

Events POST to your registered https endpoint as JSON:

EventWhen
deposit.receivedSAR arrives in your funding account
order.executedan order settles
order.failedexecution fails (order recorded as failed)
withdrawal.settleda 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.