Skip to content

Webhooks

Signed events when content is published or a form is submitted.

DocsSite data

Docs menuWebhooks

A webhook sends a signed POST to your address when something changes in a project: rebuild a static site, revalidate a page or copy form submissions into another tool.

Add endpoints in Developers → Webhooks: a name, an https address and the events you want.

Events

EventWhendata
entry.publishedan entry is published, or republished with changestype, entry (id, title, locales, revision)
entry.unpublishedan entry is taken off the live sitetype, entry
entry.deletedan entry is deletedtype, entry
type.updateda type's structure changestype, revision
form.submitteda form receives a submissionform, submission (data, page)
pingyou press Send test

Deliveries are written in the same transaction as the change and leave after it commits, so a change that fails sends nothing.

The request

HTTP
POST https://your-site.com/api/manifolio
content-type: application/json
user-agent: Manifolio-Webhooks/1
manifolio-event: entry.published
manifolio-delivery: 01a1b2c3-0000-7000-8000-000000000009
manifolio-signature: t=1760300000,v1=5f2c4e1a9b
JSON
{
  "id": "evt_01a1b2c3",
  "event": "entry.published",
  "createdAt": "2026-10-12T09:00:00.000Z",
  "project": { "id": "01a1b2c3-0000-7000-8000-000000000000", "slug": "aurora-coffee" },
  "data": { "type": "article", "entry": { "id": "01a1b2c3-0000-7000-8000-000000000001", "title": "First post", "locales": ["en", "ro"], "revision": 7 } }
}

Verifying the signature

Each endpoint has its own secret (whsec_), shown in the admin. The signature header is t=<unix seconds>,v1=<hex HMAC-SHA256 of "t.body">, computed over the raw body. Verify it before you trust anything in the request.

TypeScript
// app/api/manifolio/route.ts (Next.js)
import { revalidateTag } from "next/cache";
import { parseWebhook } from "@manifolio/sdk";

export async function POST(req: Request) {
  const body = await req.text();
  const event = await parseWebhook(process.env.MANIFOLIO_WEBHOOK_SECRET!, body, req.headers.get("manifolio-signature"));
  if (event.event === "entry.published") revalidateTag(`manifolio:${event.data.type}`);
  return new Response("ok");
}

Without the SDK, compute HMAC-SHA256(secret, t + "." + body) in hex, compare it in constant time with v1 and reject a t more than five minutes away from your clock.

Retries

  • Delivery is at least once. A retry can arrive after the first attempt succeeded, so keep the event id (it stays the same on Retry) and skip what you have already handled.
  • Any answer other than 2xx counts as a failure. Retries follow after 1 minute, 10 minutes and 1 hour, four attempts in total; then the delivery stays failed until you press Retry.
  • The timeout is 10 seconds. Redirects are not followed. The first 4 KB of your response are kept in the delivery history.
  • Addresses must be public https on the standard port. Private, loopback and metadata addresses are refused when you save the endpoint and again on every delivery.

When a form or a submission is deleted, the copies in the delivery history lose their fields too.