Register an endpoint
secret (whsec_…) shown only once — store it. It signs every
delivery to this endpoint. You can also add endpoints and rotate secrets from the dashboard
(Webhooks). Pass event_types to subscribe to a subset; omit it to receive everything.Verify the signature and handle the event
Each request carries a Return a
Plinth-Signature: t=<unix>,v1=<hmac> header. The signature is
HMAC-SHA256("<t>.<raw body>") keyed by your endpoint secret. Verify against the raw body,
before parsing JSON.Next.js — app/api/plinth/webhook/route.ts
2xx quickly to acknowledge. Any non-2xx (or a timeout) is retried.The event envelope
Every delivery has the same shape. Your handler switches ontype and reads data.object.
type and its data.object.
Delivery, retries & idempotency
- Retries. A failed delivery (non-2xx or timeout) is retried with exponential backoff — up to
8 attempts — then marked
failed. Watch every attempt under Webhooks → deliveries, and Resend any delivery manually. - Idempotency. Deliveries can arrive more than once. Treat
event.idas an idempotency key — ignore an id you’ve already processed. - Ordering. Events are delivered roughly in order but not guaranteed; rely on the resource’s
current state (or
created) rather than assuming strict order. - Security. Always verify the signature. Reject anything that doesn’t match your endpoint secret.