ChangeVault
Notifications

Outgoing webhooks

Push change events to any external system via signed HTTP POST requests.

Outgoing webhooks deliver real-time change events to any URL you control. Use them to integrate ChangeVault with incident management tools, custom dashboards, chat bots or internal automation.

Prerequisites

  • A ChangeVault Pro plan or higher
  • An HTTPS endpoint that accepts POST requests

Setting up a webhook

  1. Go to Integrations → Automations
  2. Under Outgoing Webhooks, click Add webhook
  3. Fill in:
    • Label — a name for this webhook
    • URL — your HTTPS endpoint
    • Events — select which events to deliver (change.created, change.updated, change.deleted)
  4. Click Save
  5. Copy the signing secret shown immediately after creation — it is only displayed once

Save the signing secret now. It cannot be retrieved later. If lost, delete the webhook and create a new one.

Testing a webhook

Click the Test button next to any webhook to send a test payload. The test payload uses the same format as real events.

Events

EventTrigger
change.createdA change is logged (via dashboard or API)
change.updatedA change's title, status, risk level or other fields are updated
change.deletedA change is deleted

Payload format

{
  "event": "change.created",
  "timestamp": "2025-04-07T10:00:00.000Z",
  "data": {
    "id": "uuid",
    "title": "Deployed api-service v3.1.0",
    "risk_level": "medium",
    "status": "completed",
    "organization_id": "org_...",
    "service": { "id": "uuid", "name": "api-service" },
    "host_ref": { "id": "uuid", "hostname": "web-01" },
    "tags": ["deploy", "prod"],
    "created_at": "2025-04-07T10:00:00Z"
  }
}

Verifying signatures

Every delivery includes an X-ChangeVault-Signature header. Verify it to confirm the request is genuine.

The signature is an HMAC-SHA256 hex digest of {timestamp}.{raw body}, where timestamp is the X-ChangeVault-Timestamp header value.

import crypto from "crypto";

export function verifyWebhookSignature(
  secret: string,
  rawBody: string,
  timestamp: string,
  signature: string
): boolean {
  const payload = `${timestamp}.${rawBody}`;
  const expected = crypto
    .createHmac("sha256", secret)
    .update(payload)
    .digest("hex");
  return crypto.timingSafeEqual(
    Buffer.from(expected),
    Buffer.from(signature)
  );
}

Express.js example:

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

  if (!verifyWebhookSignature(process.env.WEBHOOK_SECRET!, req.body.toString(), timestamp, signature)) {
    return res.status(401).send("Invalid signature");
  }

  const event = JSON.parse(req.body.toString());
  console.log("Received event:", event.event);
  res.sendStatus(200);
});

Request headers

HeaderValue
Content-Typeapplication/json
X-ChangeVault-EventEvent name (e.g. change.created)
X-ChangeVault-TimestampUnix timestamp in milliseconds
X-ChangeVault-SignatureHMAC-SHA256 hex signature

Delivery behaviour

  • Requests time out after 10 seconds
  • Failed deliveries are not retried automatically — use the Test button to re-send
  • Your endpoint should return a 2xx status to acknowledge the delivery

See the API reference for outgoing webhooks for technical details.

On this page