// docs / webhooks
Webhooks
FixVibe envoie des webhooks sortants signés pour les scans terminés, les échecs terminaux, les findings de haute sévérité, les alertes de monitoring live et les exécutions programmées. Les livraisons sont at-least-once et réessayées pendant environ 24 heures.
Configuration
Ouvre Compte → Webhooks, crée un endpoint HTTPS et stocke le secret à usage unique whsec_ côté récepteur. Les webhooks sont disponibles sur les plans payants.
- Crée un endpoint depuis Compte → Webhooks.
- Choisis les événements que FixVibe doit envoyer à cet endpoint.
- Copie le secret immédiatement; il n'est affiché qu'une fois et ne pourra ensuite qu'être renouvelé.
Événements
La surface d'événements de lancement couvre les moments que les équipes branchent souvent à la CI, aux alertes ou aux tickets:
- scan.completed — déclenché quand un scan passe à completed. Payload: id du scan, cible, mode, comptes par sévérité, lien vers le rapport.
- scan.failed — terminal-failure notification. Payload: scan id, failure reason, and report link when available.
- finding.created — émis pour chaque finding critical ou high. Les sévérités plus basses restent dans scan.completed par défaut pour éviter le bruit.
- monitor.alert.fired — déclenché sur le plan Unlimited quand les logs de certificate transparency, DNS ou bases de threat intelligence détectent des changements.
- schedule.run.queued — déclenché quand le scheduler met un rescan en file. Utile pour l'orchestration CI.
Format du payload
Chaque livraison utilise la même enveloppe: <code>id</code>, <code>type</code>, <code>created_at</code> et <code>data</code> spécifique à l'événement.
{
"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-..."
}
}
}Signature
FixVibe signe le corps JSON brut exact avec HMAC-SHA-256. Vérifie la signature avant de parser ou de faire confiance aux données. Headers:
fixvibe-signature: t=<timestamp>,v1=<hex hmac>fixvibe-event: scan.completedfixvibe-delivery: <uuid>(clé d'idempotence)
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.
