> For the complete documentation index, see [llms.txt](https://docs.fullwhere.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.fullwhere.com/developer/webhooks/utiliser-les-webhooks.md).

# Utiliser les webhooks

Les workflows Fullwhere peuvent déclencher un webhook vers votre système. Chaque exécution envoie une requête `POST` vers l’URL configuré.\
Pour en savoir plus sur la mise en place d'un webhook via les workflows Fullwhere, consulter notre [article dédié](/automatisations/workflows.md). <mark style="color:$danger;">//LINK TODO</mark>

## À savoir

Les appels Webhook seront toujours des requêtes `POST`.

Fullwhere considère l’appel comme réussi uniquement si votre endpoint renvoie un code `2xx` (200-299).

## Interprétation des webhooks

### En-têtes envoyés

Les Headers suivant seront toujours présents dans la requête :

* `Content-Type: application/json`
* `User-Agent: Fullwhere-Workflow-Webhook`
* `X-Fullwhere-Webhook-Timestamp: <timestamp>`
* `X-Fullwhere-Webhook-Signature: sha256=<signature>`

Vous pouvez aussi [configurer](/automatisations/workflows.md) <mark style="color:$danger;">// LINK TODO</mark> des en-têtes personnalisés. Ils sont fusionnés avec les en-têtes système. Si un header personnalisé utilise le même nom qu'un header Fullwhere, la valeur renvoyée sera celle du header Fullwhere.

### Corps de la requête

```json
{
  "event": "workflow.action.webhook",
  "workflow": {
    "id": "workflow_id",
    "name": "Nom du workflow"
  },
  "action": {
    "id": "action_id",
    "key": "action_key",
    "description": "Description de l'action"
  },
  "feedback": {
    "id": "feedback_content_id",
    "contextId": "feedback_id"
  },
  "metadata": {
    "key": "value"
  }
}
```

Chaque champ correspond à la structure suivante :

* `event` : valeur fixe `workflow.action.webhook`
* `workflow.id` : uuid du workflow
* `workflow.name` : nom du workflow
* `action.id` : uuid de l’action du workflow
* `action.key` : clé unique de l’action
* `action.description` : description de l’action
* `feedback.id` : uuid de feedback associé
* `feedback.contextId` : uuid du contexte associé
* `metadata` : paires clé-valeur définies dans la configuration du webhook

## Vérifier les webhooks

### Recommandations

Vérifier un webhook est une étape de sécurité essentielle. Sans vérification, un tiers peut envoyer une requête vers votre endpoint en imitant Fullwhere. Dans ce cas, votre application peut traiter un événement falsifié comme s’il était légitime. Cela peut déclencher des actions métier non voulues ou exposer une faille exploitable.

Pour éviter cela, chaque webhook est **signé** à l'aide d'une clé unique. Cette signature permet ensuite de vérifier que le webhook provient bien de Fullwhere, et de ne le traiter que si tel est le cas.

Une autre faille de sécurité potentielle réside dans ce que l’on appelle les « attaques par rejeu ». Une attaque par rejeu se produit lorsqu’un attaquant intercepte une charge utile valide (y compris la signature) et la retransmet à votre terminal. Cette charge utile passera la validation de la signature et sera donc traitée.\
Pour atténuer ce risque, un timestamp (en-tête `Fullwhere-Webhook-Timestamp`) est inclus dans chaque requête, indiquant l’heure à laquelle la tentative de webhook a eu lieu. Nous vous recommandons de rejeter les webhooks dont le timestamp s’écarte de plus de cinq minutes (en avant ou en arrière) par rapport à l’heure actuelle.

### Éléments de signatures

Chaque appel de webhook comprend donc deux en-têtes contenant des informations supplémentaires utilisées à des fins de vérification :

* `X-Fullwhere-Webhook-Timestamp: <timestamp>` : timestamp en seconde
* `X-Fullwhere-Webhook-Signature: sha256=<signature>` : la signature encodée en Base64

### Construction de la chaîne signée

La chaîne signée correspondant au `timestamp` et au `payload`, séparés par le caractère `.` :

```
<timestamp>.<rawBody>
```

`timestamp` correspondant au timestamp de l'envoi du webhook, présent dans le header `X-Fullwhere-Webhook-Timestamp` et `rawBody` est le JSON sérialisé de la requête.

L’en-tête reçu a donc cette forme :

```
X-Fullwhere-Webhook-Signature: sha256=<hex>
```

### Déterminer la signature attendue

Chaque webhook est signé avec l’algorithme `HMAC SHA-256`. Le secret utilisé est celui du compte Fullwhere.

Pour calculer la signature attendue, vous devez donc appliquer l'algorithme HMAC à la chaîne signée en utilisant le secret de votre compte Fullwhere.

Cette signature générée doit correspondre à l'une de celles envoyées dans l'en-tête `X-Fullwhere-Webhook-Signature`.

**Exemple de code (NodeJS)**

```js
const crypto = require('crypto');
function verifyFullwhereWebhookSignature({
  rawBody,
  timestamp,
  signature,
  webhookHmacSecret,
}) {
  const expectedSignature = crypto
    .createHmac('sha256', webhookHmacSecret)
    .update(`${timestamp}.${rawBody}`)
    .digest('hex');

  const receivedSignature = signature.replace(/^sha256=/, '');

  return crypto.timingSafeEqual(
    Buffer.from(expectedSignature, 'hex'),
    Buffer.from(receivedSignature, 'hex'),
  );
}
```

### Générer le secret de votre compte Fullwhere

Pour vérifier les webhooks, vous aurez donc besoin de générer votre secret `HMAC`.

Pour cela, en tant que membre Administrateur de votre compte Fullwhere, accédez à la section Paramètres, puis Développeurs, et dans l'onglet Webhooks, générez ou re-générez votre secret `HMAC`.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.fullwhere.com/developer/webhooks/utiliser-les-webhooks.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
