Webhooks

Webhooks

Available Events

  • run.started: fired when an operator starts a production run
  • run.closed: fired when a run is closed and challans are generated
  • order.created: fired when a new order is added to the queue
  • dispatch.challan_ready: fired when a challan PDF is ready for download
  • inventory.low_stock: fired when stock drops below configured threshold

Payload Format

json
{
  "event": "run.closed",
  "timestamp": "2026-06-06T14:30:00Z",
  "tenantId": "your_mill_id",
  "data": {
    "runId": "run_01J2XKPZ8N4G",
    "runNumber": "20260606-007",
    "totalWastePct": 0.38,
    "challanIds": ["chl_01J2XKA", "chl_01J2XKB"]
  }
}

Security & Validation

Each webhook delivery includes an X-Deckle-Signature header containing an HMAC-SHA256 signature of the payload body, signed with your webhook secret. Always verify this signature before processing the payload.

typescript
import crypto from "crypto";

function verifyWebhook(body: string, signature: string, secret: string) {
  const expected = crypto
    .createHmac("sha256", secret)
    .update(body)
    .digest("hex");
  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expected)
  );
}

Retry Behaviour

Failed webhook deliveries (non-2xx response or connection timeout) are retried up to 5 times with exponential backoff: 1 min, 5 min, 30 min, 2 hr, 8 hr. After 5 failures the event is marked as permanently failed and logged in Settings → Webhooks → Delivery Log for manual inspection.

Was this page helpful?

Something unclear or missing? Reach out and we'll update this page.

Give Feedback