Skip to main content
This guide walks you through setting up outbound webhooks to send HTTP notifications to external services when data changes in your collections.

Prerequisites

  • A running SnackBase instance
  • At least one collection with data
  • An external HTTPS endpoint to receive webhooks (for production)

Setup

1

Create a Webhook

Create a webhook using the API or SDK:
const webhook = await client.webhooks.create({
  url: "https://your-server.com/webhooks/orders",
  collection: "orders",
  events: ["create", "update"],
});

// IMPORTANT: Save this secret
console.log("Webhook secret:", webhook.secret);
The webhook secret is only returned in the creation response. Store it securely — you’ll need it to verify signatures.
2

Store the Signing Secret

Store the returned secret in your server’s environment variables:
export SNACKBASE_WEBHOOK_SECRET="your-64-char-hex-secret"
Never hardcode the secret in your source code.
3

Implement Signature Verification

Every webhook delivery includes an X-SnackBase-Signature header. Verify it on your server:
const crypto = require("crypto");

function verifyWebhook(payload, secret, signatureHeader) {
  const expected =
    "sha256=" +
    crypto.createHmac("sha256", secret).update(payload).digest("hex");
  return crypto.timingSafeEqual(
    Buffer.from(expected),
    Buffer.from(signatureHeader)
  );
}

// Express middleware
app.post("/webhooks/orders", express.raw({ type: "application/json" }), (req, res) => {
  const signature = req.headers["x-snackbase-signature"];
  if (!verifyWebhook(req.body, process.env.SNACKBASE_WEBHOOK_SECRET, signature)) {
    return res.status(401).send("Invalid signature");
  }

  const event = JSON.parse(req.body);
  console.log("Event:", event.event);
  console.log("Record:", event.record);

  res.status(200).send("OK");
});
4

Test Your Webhook

Use the built-in test endpoint to verify everything works:
const result = await client.webhooks.test("webhook-id");
console.log(result.success); // true
console.log(result.status_code); // 200
5

Monitor Deliveries

Check delivery history to debug issues:
const deliveries = await client.webhooks.listDeliveries("webhook-id");

for (const d of deliveries.items) {
  console.log(`${d.event} - ${d.status} (HTTP ${d.response_status})`);
  if (d.status === "failed") {
    console.log("Error:", d.response_body);
  }
}

Adding Filters

Only fire webhooks when specific conditions are met:
const webhook = await client.webhooks.create({
  url: "https://your-server.com/webhooks/high-value",
  collection: "orders",
  events: ["create"],
  filter: 'total >= 500 and status = "confirmed"',
});

Troubleshooting

Check the delivery history for error details. Common causes:
  • Your endpoint is returning non-2xx status codes
  • Your endpoint is taking longer than 30 seconds to respond
  • DNS resolution is failing for your URL
Ensure you’re verifying against the raw request body (bytes), not a parsed/re-serialized JSON object. The signature is computed over the exact bytes sent.
  • Verify the webhook is enabled
  • Check that the event type matches (create, update, delete)
  • If using a filter, verify the expression matches your record data
  • Filters that fail to evaluate will still fire the webhook (fail-open)
In production, SnackBase requires HTTPS URLs. For local development, HTTP is allowed. Private IPs (localhost, 10.x, 192.168.x) are also blocked in production.

Next Steps