Webhooks

Receive signed FortyOne events without polling.

Webhooks send changes to an HTTPS endpoint you control. Managing endpoints requires a workspace administrator token with webhooks:manage.

Delivery flow

StageWhat happens
RegisterAdd a public HTTPS endpoint and choose event subscriptions
SignFortyOne signs the exact request body with the endpoint secret
DeliverYour server validates the signature, records the delivery ID, and responds quickly
ProcessBusiness work runs asynchronously after the response
RetryTransient failures are retried with the same delivery identity

Available events

ResourceEvents
Storiesstory.created, story.updated, story.deleted
Commentscomment.created, comment.updated, comment.deleted

Use the Webhooks API reference for endpoint paths and request schemas.

Verify every delivery

Verification must use the raw body bytes before JSON parsing. Check the signing version, timestamp tolerance, and HMAC signature with a constant-time comparison. Reject a delivery when any check fails.

const expected = createHmac("sha256", secret)
  .update(`${timestamp}.${rawBody}`)
  .digest("hex");

if (!timingSafeEqual(Buffer.from(expected), Buffer.from(signature))) {
  throw new Error("Invalid webhook signature");
}

Store the delivery ID before acknowledging the request so a retry cannot apply the event twice. Return a 2xx response after durable receipt, then process the event outside the request path.

Secret rotation

Rotation shows the new secret once and keeps the previous secret valid for a bounded overlap. During that window, verify against both active generations. Remove the old secret from your secret manager after the overlap ends.

On this page