FixVibe

// docs / webhooks

Webhooks

FixVibe sends signed outbound webhooks for scan completion, terminal failures, high-severity findings, live monitor alerts, and scheduled runs. Deliveries are at-least-once and retry for about 24 hours.

Setup

Open Account โ†’ Webhooks, create an HTTPS endpoint, and store the one-time whsec_ secret in your receiver. Webhooks are available on paid plans.

  1. Create an endpoint from Account โ†’ Webhooks.
  2. Choose which events FixVibe should send to that endpoint.
  3. Copy the secret immediately; it is shown once and can only be rotated later.

Events

The launch event surface covers the moments teams usually wire into CI, alerting, or ticketing:

  • scan.completed โ€” fires when a scan transitions to completed. Payload: scan id, target, mode, severity-bucket counts, link to the report.
  • scan.failed โ€” terminal-failure notification. Payload: scan id, failure reason, and report link when available.
  • finding.created โ€” emitted per critical or high finding. Lower severities collapse into scan.completed by default to avoid event spam.
  • monitor.alert.fired โ€” fires on the Unlimited plan when certificate transparency logs, DNS records, or threat-intelligence databases detect changes.
  • schedule.run.queued โ€” fires when the scheduler enqueues a re-scan. Useful for CI orchestration.

Payload shape

Every delivery uses the same envelope: <code>id</code>, <code>type</code>, <code>created_at</code>, and event-specific <code>data</code>.

json
{
  "id": "8f1c4e2a-8c3a-4b6f-9c0d-9b1e8f3c2a4d",
  "type": "scan.completed",
  "created_at": "2026-05-15T10:20:30.000Z",
  "data": {
    "scan": {
      "id": "8f1c4e2a-8c3a-4b6f-9c0d-9b1e8f3c2a4d",
      "target_hostname": "staging.example.com",
      "mode": "passive",
      "status": "completed",
      "findings_count": { "critical": 0, "high": 1, "medium": 2, "low": 3, "info": 4 },
      "report_url": "https://fixvibe.app/dashboard/scans/8f1c4e2a-..."
    }
  }
}

Signing

FixVibe signs the exact raw JSON body with HMAC-SHA-256. Verify the signature before parsing or trusting event data. Headers:

  • fixvibe-signature: t=<timestamp>,v1=<hex hmac>
  • fixvibe-event: scan.completed
  • fixvibe-delivery: <uuid> (idempotency key)
ts
import { createHmac, timingSafeEqual } from "node:crypto";

function verify(rawBody: string, header: string, secret: string) {
  const parts = Object.fromEntries(header.split(",").map((p) => p.split("=")));
  const signed = `${parts.t}.${rawBody}`;
  const expected = createHmac("sha256", secret).update(signed).digest("hex");
  const received = Buffer.from(parts.v1 ?? "", "hex");
  const calculated = Buffer.from(expected, "hex");
  return received.length === calculated.length && timingSafeEqual(received, calculated);
}

Retries

Any non-2xx response, timeout, DNS failure, or delivery safety rejection is retried with exponential backoff for about 24 hours. Delivery rows show response status, a short response excerpt, attempt count, and dead-letter state in Account โ†’ Webhooks.

Webhooks โ€” Docs ยท FixVibe