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.
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)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");
}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")2xx are retried.max_attempts (default 6), the delivery moves to dead and stops retrying. Replay manually from the admin console.certificate.issuedapplication.submittedvisa.status_changedjob.application_submittedpayment.completedthread.reply_createdevent.createdUse 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.