Skip to main content
In addition to Slack, you can deliver DriftGuard check results to any HTTPS endpoint — your own backend, PagerDuty, a monitoring system, or a custom incident pipeline.

Register a Webhook

curl -s -X POST https://api.driftguard.dev/api/v1/webhooks \
  -H "X-API-Key: $DRIFTGUARD_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://your-app.com/webhooks/driftguard",
    "events": ["breaking"],
    "contract_id": "your_contract_id_here"
  }'
FieldRequiredDescription
urlHTTPS URL DriftGuard will POST check results to. HTTP is rejected.
eventsArray of result types that trigger delivery: breaking, warning, pass
contract_idScope to a single contract ID, or null to fire for all contracts
The url must use HTTPS. HTTP endpoints will be rejected with a 400 error.
Save the id and secret from the response — the secret is shown only once:
{
  "id": "your_webhook_id_here",
  "url": "https://your-app.com/webhooks/driftguard",
  "events": ["breaking"],
  "contract_id": "your_contract_id_here",
  "active": true,
  "secret": "whsec_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
  "created_at": "2026-03-01T19:22:00Z"
}

Payload Format

When a check completes with a result that matches your events list, DriftGuard POSTs the full check result JSON to your endpoint:
{
  "id": "your_check_id_here",
  "contract_id": "your_contract_id_here",
  "result": "breaking",
  "severity": 70,
  "diff": {
    "removed": ["email"],
    "type_changes": [
      { "column": "created_at", "from": "timestamp", "to": "string" }
    ],
    "added": []
  },
  "credits_used": 1,
  "created_at": "2026-03-01T18:00:14Z"
}
Your endpoint must return a 2xx response to confirm receipt.

Verifying Webhook Signatures

Every delivery includes an X-DriftGuard-Signature header containing an HMAC-SHA256 hex digest of the raw request body, signed with your webhook secret. Always verify this signature before trusting or acting on the payload.
import hmac
import hashlib
from flask import Flask, request, jsonify

app = Flask(__name__)
WEBHOOK_SECRET = "whsec_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

def verify_signature(payload: bytes, signature: str) -> bool:
    expected = hmac.new(
        WEBHOOK_SECRET.encode(),
        payload,
        hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(expected, signature)

@app.route("/webhooks/driftguard", methods=["POST"])
def handle():
    sig = request.headers.get("X-DriftGuard-Signature", "")

    if not verify_signature(request.data, sig):
        return "Unauthorized", 401

    payload = request.json
    result = payload.get("result")
    severity = payload.get("severity")

    print(f"DriftGuard check result: {result} (severity: {severity})")

    # Your alerting logic here

    return jsonify({"ok": True})
// Node.js / Express example
const crypto = require("crypto");

function verifySignature(rawBody, signature, secret) {
  const expected = crypto
    .createHmac("sha256", secret)
    .update(rawBody)
    .digest("hex");
  return crypto.timingSafeEqual(
    Buffer.from(expected),
    Buffer.from(signature)
  );
}

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

  if (!verifySignature(req.body, sig, process.env.WEBHOOK_SECRET)) {
    return res.status(401).send("Unauthorized");
  }

  const payload = JSON.parse(req.body);
  console.log("Result:", payload.result, "Severity:", payload.severity);

  res.json({ ok: true });
});
Always use a constant-time comparison (hmac.compare_digest in Python, crypto.timingSafeEqual in Node.js) to prevent timing attacks.

Delivery and Retries

DriftGuard delivers payloads in a background thread with automatic retries if your endpoint does not return a 2xx response:
AttemptTiming
1st (initial)Immediate
2nd retry5 seconds after failure
3rd retry25 seconds after failure
After 3 failed attempts the delivery is abandoned for that check. Ensure your endpoint responds quickly — long-running logic should be handled asynchronously after returning 200.

Listing Webhooks

curl -s https://api.driftguard.dev/api/v1/webhooks \
  -H "X-API-Key: $DRIFTGUARD_KEY"
[
  {
    "id": "your_webhook_id_here",
    "url": "https://your-app.com/webhooks/driftguard",
    "events": ["breaking"],
    "contract_id": "your_contract_id_here",
    "active": true,
    "created_at": "2026-03-01T19:22:00Z"
  }
]

Deleting a Webhook

curl -s -X DELETE https://api.driftguard.dev/api/v1/webhooks/your_webhook_id_here \
  -H "X-API-Key: $DRIFTGUARD_KEY"

Create Webhook

Full API reference for registering webhooks.

Slack Alerts

Point a webhook at Slack for instant drift notifications.