---
title: Webhooks de veille
description: Recevez vos actualités de veille en HTTP POST signé (HMAC-SHA256) - CRM, Slack, n8n.
---

Insourcia peut pousser chaque actualité de veille vers votre endpoint HTTP en temps quasi réel (webhook sortant, comme Stripe ou GitHub). Chaque livraison est **signée (HMAC-SHA256)**, **retentée** et **journalisée**.

Configuration : **Actualités → ⚙️ Paramètres de notifications → Avancé → Webhooks**.

Là où l'API REST et le MCP répondent quand *vous* les appelez, le webhook fait l'inverse : Insourcia **écrit dans vos systèmes** pour déclencher une action (créer une tâche CRM, alerter un canal Slack, lancer un scénario n8n) sans humain dans la boucle.

> Disponible sur tous les plans. **Free** : 5 livraisons/jour (même limite que le flux RSS et le digest email). **Pro** : illimité. Nombre d'endpoints : Free 1, Pro 5. Une adresse email vérifiée est requise.

## Livraison

Pour chaque évènement, un `POST` est envoyé à votre URL avec ces en-têtes :

| En-tête | Description |
|---|---|
| `X-Insourcia-Signature` | `sha256=<hex>` - HMAC-SHA256 sur `{X-Insourcia-Timestamp}.{corps brut}` avec le secret de l'endpoint. |
| `X-Insourcia-Timestamp` | Horodatage Unix (secondes), régénéré à chaque tentative. |
| `X-Insourcia-Delivery` | `delivery_id` (clé d'idempotence, aussi dans le corps). |

- **Accusé de réception** : répondez **2xx**. Sinon reprises `1 min, 5 min, 30 min, 2 h, 6 h`, puis l'endpoint est désactivé après plusieurs échecs consécutifs (et vous êtes notifié).
- **Aucune garantie d'ordre** : dédupliquez sur `delivery_id`.
- L'URL doit être en **https** et publique (les adresses internes sont refusées). Les redirections ne sont pas suivies.

## Vérifier la signature

Recalculez le HMAC sur les octets exacts `"{timestamp}.{corps brut}"` avec le secret (préfixe `whsec_`) et comparez en temps constant. Rejetez un horodatage hors tolérance (anti-rejeu).

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

// rawBody = le corps brut reçu (Buffer/string), NON re-sérialisé.
function verify(rawBody, headers, secret) {
  const ts = headers["x-insourcia-timestamp"];
  const sig = headers["x-insourcia-signature"]; // "sha256=<hex>"
  if (!ts || !sig) return false;
  if (Math.abs(Date.now() / 1000 - Number(ts)) > 300) return false; // 5 min
  const expected =
    "sha256=" +
    createHmac("sha256", secret).update(`${ts}.${rawBody}`).digest("hex");
  const a = Buffer.from(sig);
  const b = Buffer.from(expected);
  return a.length === b.length && timingSafeEqual(a, b);
}
```

> Signez/vérifiez sur le **corps brut** reçu, pas sur un JSON re-sérialisé : `JSON.stringify(parsed)` ne reproduit pas forcément les octets d'origine.

## Payloads

### `company.alert`

Envoyé pour chaque nouvel évènement détecté sur une entreprise d'une veille surveillée.

```json
{
  "event": "company.alert",
  "schema_version": "1",
  "delivery_id": "clz1a2b3c4d5e6f7",
  "occurred_at": "2026-07-14T06:00:00.000Z",
  "source": { "type": "list", "id": "clh0list123", "name": "Cibles LBO" },
  "alert": {
    "siren": "552081317",
    "company_name": "GO SPORT FRANCE",
    "category": "procedure_collective",
    "label": "Procédure collective",
    "summary": "Ouverture de liquidation judiciaire",
    "occurred_on": "2026-07-12",
    "date_note": "effet 12/07/2026",
    "company_url": "https://app.insourcia.io/company/552081317"
  }
}
```

- `source` : la veille (recherche sauvegardée ou liste) à l'origine, `type` = `saved_search` ou `list`.
- `alert.category` : type brut de l'évènement (`procedure_collective`, `dirigeant_entered`, `cession`, `nouveaux_comptes`, `radiation`…) ou, à défaut, le type d'alerte.

### `webhook.ping`

Envoyé par le bouton « Tester » pour valider votre endpoint et votre vérification de signature.

```json
{
  "event": "webhook.ping",
  "schema_version": "1",
  "delivery_id": "whp_1f2e3d4c",
  "occurred_at": "2026-07-14T06:00:00.000Z",
  "message": "Insourcia webhook test event"
}
```

## Portée (routing)

Chaque endpoint peut être limité, via le bouton **Portée**, à certaines **veilles** et/ou certains **groupes de signaux** (procédures collectives, dirigeants, cessions/M&A, comptes annuels, marchés publics, liens de groupe, entrées/sorties de veille). Les deux dimensions sont combinées ; vide = tout. Vous pouvez ainsi router les signaux distressed vers un canal Slack et tout le reste vers votre CRM.
