Webhooks
Be told when something happens instead of polling for it.
We POST to your URL when something happens, so you do not have to poll. Add an endpoint under Settings → Webhooks, choose events (or none, meaning everything including events added later), and copy the signing secret — it is shown once.
Verifying a delivery
Every request carries Nook-Signature in Stripe’s shape: t=<unix>,v1=<hmac>, computed over {t}.{body} with your secret. The timestamp is inside the signed string, so a captured request cannot be replayed later with its clock moved forward.
const [t, v1] = header.split(",").map((p) => p.split("=")[1]);
const expected = createHmac("sha256", secret)
.update(`${t}.${rawBody}`)
.digest("hex");
// compare in constant time, and reject anything older than your toleranceCheck it before you need it
Settings → Webhooks has a Send test button on every endpoint. It queues a delivery through the same signing and retry path as a real event, so a green result means the real thing will work rather than that a special case did.
The test arrives with event ping — a name nothing in the product ever emits, so a receiver that switches on the event name cannot mistake it for a real contact being created — and a payload that says { test: true }.
Retries and duplicates
A failed delivery retries with backoff over about three days; a 429 retries every ten minutes for seven attempts. Nook-Delivery-Id is stable across every retry, so deduplicate on it — otherwise a retry means the same event is processed twice and the symptom shows up as duplicate work rather than as a webhook problem.
An endpoint that fails repeatedly is switched off rather than retried forever, and the Settings screen says so on the row with the failure count. Deliveries are kept for 30 days with their status, HTTP code, attempt count and duration, and any of them can be resent.