EndpointOS

Webhooks

Signed delivery, retries with backoff, and how to verify a payload.

All docs

Webhooks

Webhooks notify your systems when records change. Configure an endpoint URL, pick the events to subscribe to, and EndpointOS POSTs a signed JSON payload to your URL.

Creating an endpoint

Open the Webhooks tab on a project, click New endpoint, paste your HTTPS URL, pick the events. The signing secret is shown once. Copy it now.

Signature verification

Every delivery includes an X-EndpointOS-Signature header containing an HMAC-SHA256 of the raw request body, computed with your signing secret. The format mirrors Stripe's pattern (t=timestamp,v1=hex). Verify it before trusting the payload:

const sig = req.headers["x-endpointos-signature"];
const [tsPart, v1Part] = sig.split(",");
const timestamp = tsPart.split("=")[1];
const provided = v1Part.split("=")[1];
const expected = crypto
  .createHmac("sha256", WEBHOOK_SECRET)
  .update(timestamp + "." + rawBody)
  .digest("hex");
if (!crypto.timingSafeEqual(Buffer.from(provided), Buffer.from(expected))) {
  return res.status(401).end();
}

SSRF protection

Endpoint URLs are validated on save and re-validated on every fire. Internal addresses (RFC1918 private ranges, link-local, loopback, IPv4-mapped IPv6) are rejected. This protects your team from accidentally pointing a webhook at an internal service.

Delivery + retries

Each delivery attempt is recorded in the endpoint's delivery log: timestamp, response status, response body (truncated), duration. Today, delivery is fire-and-forget; durable retry with exponential backoff is on the next-up roadmap (see /changelog). Plan accordingly: webhooks are best-effort notifications, not a system of record.

Rotating + disabling

Rotate the signing secret from the endpoint's settings (issues a new secret, invalidates the old). Disable the endpoint to pause all delivery without deleting its history.

Previous: Billing and subscriptions · Next: Logs and audit

Webhooks · EndpointOS docs | EndpointOS