Webhooks

Webhook subscriptions let HIGAET push platform events to a URL you control. Each subscription is tied to an API key and receives a signing_secret for signature verification. Create and manage them from the admin console.

Headers we send

X-HIGAET-Event        e.g. certificate.issued
X-HIGAET-Timestamp    unix seconds at dispatch time
X-HIGAET-Signature    HMAC-SHA256(timestamp + "." + raw_body, signing_secret)
X-HIGAET-Delivery-Id  unique per attempt (uuid)

Signature verification (Node)

import { createHmac, timingSafeEqual } from "node:crypto";

function verify(req, secret) {
  const ts = req.headers["x-higaet-timestamp"];
  const sig = req.headers["x-higaet-signature"];
  const expected = createHmac("sha256", secret).update(`${ts}.${req.rawBody}`).digest("hex");
  const a = Buffer.from(sig); const b = Buffer.from(expected);
  if (a.length !== b.length || !timingSafeEqual(a, b)) throw new Error("bad signature");
  // Reject events older than 5 minutes to prevent replay
  if (Math.abs(Date.now() / 1000 - Number(ts)) > 300) throw new Error("stale timestamp");
}

Signature verification (Python)

import hmac, hashlib, time
def verify(ts, sig, raw_body, secret):
    expected = hmac.new(secret.encode(), f"{ts}.{raw_body}".encode(), hashlib.sha256).hexdigest()
    if not hmac.compare_digest(sig, expected): raise ValueError("bad signature")
    if abs(time.time() - int(ts)) > 300: raise ValueError("stale timestamp")

Retry policy

Event catalog (v1)

Local testing

Use a tunnel (e.g. ngrok, cloudflared) to expose your local server, then register the public URL as a subscription. Trigger an event from the platform and inspect the delivery in the admin Recent deliveries table — replay until your handler is correct.