OGsmithStart free

Docs

Webhooks

Add an endpoint under Dashboard → Batches & webhooks and we POST JSON to it when something happens: batch.completed and quota.threshold.

POST https://your-app.example.com/hooks/ogsmith
X-OGsmith-Event: batch.completed
X-OGsmith-Delivery: 6f1c…
X-OGsmith-Signature: t=1787840000,v1=9a3f…

{ "id": "6f1c…", "event": "batch.completed",
  "createdAt": "2026-08-27T15:51:02.000Z",
  "data": { "batchId": "…", "total": 14, "done": 14, "failed": 0 } }

The signing secret is shown once when you add the endpoint. Verify a delivery by recomputing the HMAC over timestamp + "." + body. The timestamp is signed together with the body rather than sent beside it, so nobody can replay a captured request with a fresh timestamp:

import { createHmac, timingSafeEqual } from "crypto";

function verify(header, body, secret) {
  const parts = Object.fromEntries(header.split(",").map(p => p.split("=")));
  const age = Math.abs(Date.now() / 1000 - Number(parts.t));
  if (!(age < 300)) return false;                 // reject replays
  const expected = createHmac("sha256", secret)
    .update(`${parts.t}.${body}`)
    .digest("hex");
  return timingSafeEqual(Buffer.from(parts.v1, "hex"), Buffer.from(expected, "hex"));
}

Reply with any 2xx. We retry a failed delivery with a growing delay, up to five attempts, and record every attempt so you can see what happened. Endpoints must be public addresses: we refuse private, loopback and cloud metadata addresses when you add them, and we don't follow redirects.