Webhooks

Rebuild or revalidate your site when content changes. Configure them in Settings → Webhooks.

Events

entry.published, entry.unpublished, entry.deleted, entry.moved (moved to another folder, reordered, or a live page got another web address; with from and the new path), release.published, asset.created (also when restored from the trash, with restored: true), asset.updated, asset.deleted (moved to the trash or deleted for good), form.submitted (with the form key and the submitted values, e.g. to add newsletter signups to your mailing tool), menu.updated (a navigation menu was saved, created or deleted), redirect.updated (redirects were added, changed or removed, also when a page's new path added one; with count).

POST https://your-site.example/api/revalidate
{
  "type": "entry.published",
  "spaceId": "spc_…",
  "cv": 1760000000000,
  "data": { "entryId": "ent_…", "path": "/blog/hello" },
  "timestamp": "2026-10-12T10:00:00.000Z"
}

Verifying signatures

Deliveries follow Standard Webhooks: headers webhook-id, webhook-timestamp and webhook-signature (v1,<base64 HMAC-SHA256 of "id.timestamp.body">, keyed with the webhook's whsec_… secret). verifyWebhook from @blokcms/client checks them (any Standard Webhooks library does too):

import { verifyWebhook } from "@blokcms/client";

const event = await verifyWebhook(env.BLOK_WEBHOOK_SECRET, request.headers, await request.text());
if (!event) return new Response("Invalid signature", { status: 401 });
blok.setCacheVersion(event.cv);   // read the new content right away, not a cached version

Pass the raw body, before parsing it. Deliveries signed more than 5 minutes ago are refused (toleranceSeconds).

Retries

Non-2xx responses and timeouts are retried with exponential backoff (30 seconds up to an hour), for up to 8 attempts. Every attempt is listed in the webhook's delivery log in the admin, where you can also send a test event.