Skip to content

Automate with Webhooks

Receive real-time notifications when content changes in your Vivreal collections

advanced25 min readFor developers

Automate with Webhooks

Webhooks let your application react to changes in Vivreal in real time. When a content item (collection object) is created, updated, or deleted, Vivreal sends an HTTP POST to your endpoint with the event payload.

Prerequisites

  • A Vivreal account with an active group
  • A publicly accessible server or service (e.g. Express.js, Vercel serverless function, or a tool like ngrok for local development)
  • Basic knowledge of Node.js

Create a webhook receiver

Set up a simple Express.js server that verifies the signature and handles incoming events. Note the use of express.raw() — the signature is computed over the raw request body, so you must NOT parse the body as JSON before verifying.

const express = require("express");
const crypto = require("crypto");

const app = express();

const WEBHOOK_SECRET = process.env.WEBHOOK_SECRET; // from Vivreal

function verifySignature(rawBody, signatureHeader) {
  // Header format: "sha256=<hex>" — strip the prefix
  if (!signatureHeader || !signatureHeader.startsWith("sha256=")) {
    return false;
  }
  const received = signatureHeader.slice("sha256=".length);

  const expected = crypto
    .createHmac("sha256", WEBHOOK_SECRET)
    .update(rawBody)
    .digest("hex");

  const a = Buffer.from(received, "hex");
  const b = Buffer.from(expected, "hex");
  if (a.length !== b.length) return false;
  return crypto.timingSafeEqual(a, b);
}

app.post(
  "/webhooks/vivreal",
  express.raw({ type: "application/json" }),
  (req, res) => {
    const signature = req.headers["x-vivreal-signature"];

    if (!verifySignature(req.body, signature)) {
      return res.status(401).json({ error: "Invalid signature" });
    }

    const { event, data } = JSON.parse(req.body.toString("utf8"));
    console.log(`Received event: ${event}`, data);

    switch (event) {
      case "content.created":
        // Handle new content item
        break;
      case "content.updated":
        // Handle update
        break;
      case "content.deleted":
        // Handle deletion
        break;
      default:
        console.log("Unknown event type:", event);
    }

    res.status(200).json({ received: true });
  },
);

app.listen(3001, () => console.log("Webhook receiver on :3001"));

Expose your local server

If you are developing locally, use ngrok to create a public URL:

ngrok http 3001

Copy the forwarding URL (e.g. https://abc123.ngrok.io).

Configure the webhook in Vivreal

In the portal, go to Group SettingsWebhooks+ New Webhook. Fill in:

  • URL: Your public endpoint (e.g. https://abc123.ngrok.io/webhooks/vivreal)
  • Events: Select the events you want to receive (content.created, content.updated, content.deleted)
  • Secret: Vivreal generates an HMAC secret. Copy it and set it as WEBHOOK_SECRET in your server environment.

Click Save to activate the webhook.

Test with a sample payload

Create or edit a content item in any collection. Your webhook receiver should log the incoming event within a few seconds. The payload structure looks like this:

{
  "event": "content.created",
  "timestamp": "2026-03-15T12:00:00.000Z",
  "groupID": "68f27fec32e7acbb755c087e",
  "dbKey": "general_shared",
  "data": {
    "_id": "68f28012a3c1d4b001234567",
    "refID": "68f27fff9a2b4c0012345001",
    "objectValue": {
      "title": "New Post",
      "tags": ["announcement"]
    }
  }
}

Handle failures gracefully

Vivreal's delivery pipeline sits behind an SQS queue. If your endpoint returns a non-2xx status or times out, the event is redelivered according to the queue's visibility-timeout and maxReceiveCount policy. After 10 consecutive failures for a single endpoint, that endpoint is automatically disabled.

Your endpoint should:

  • Return a 2xx status code within 5 seconds to acknowledge receipt.
  • Process heavy work asynchronously (e.g. queue it) rather than blocking the response.
  • Use the X-Vivreal-Delivery header for idempotency — the same event may be delivered more than once.
  • Log failures for debugging — check the Webhook Delivery section in the portal for delivery history.

Always verify the X-Vivreal-Signature header (format: sha256=<hex>) before processing a webhook. Without verification, an attacker could send fake events to your endpoint.

During development, return a 200 immediately and log the payload. Once your logic is stable, add signature verification and error handling.

Common Use Cases

Use CaseEventAction
Rebuild static sitecontent.updatedTrigger Amplify rebuild
Send notificationcontent.createdPost to Slack or email
Sync to external DBAnyUpsert into Postgres / Algolia
Invalidate cachecontent.updatedPurge CDN cache key

Next Steps