Webhooks (JSON)
Une règle Webhook envoie en POST chaque réponse correspondante, au format JSON, vers une URL que vous fournissez. Utilisez-la pour alimenter un CRM, un outil de tableur, votre propre serveur ou une plateforme d'automatisation comme Zapier, Make ou n8n.
Créer une règle webhook
- Cliquez sur + Nouvelle règle et choisissez Webhook
- Quand : gardez Chaque réponse ou choisissez Seulement après approbation / En cas de rejet et définissez un approbateur. Ajoutez des conditions sous Seulement si pour n'envoyer que les réponses correspondantes
- Destinataire : collez l'URL de votre destination (HTTPS uniquement). Il n'y a pas d'étape Message : la règle envoie un payload JSON fixe. Voir le payload, sous l'URL, l'affiche avec les questions de votre formulaire, prêt à copier
- Cliquez sur Créer la règle, puis copiez le secret de signature affiché une seule fois (voir ci-dessous)

Envoyer un test envoie un payload d'exemple signé vers la destination et affiche le statut HTTP renvoyé. Les URL enregistrées sont stockées chiffrées et affichées masquées ; cliquez sur Remplacer pour en coller une nouvelle.
Le payload
Chaque requête est un POST, Content-Type: application/json, avec ce corps :
{
"version": 1,
"event": "submitted",
"form": { "id": "1AbC...", "name": "Workshop sign-up" },
"response": {
"id": "a3f1...",
"submittedAt": "2026-01-31T09:30:00.000Z",
"respondentEmail": "respondent@example.com",
"answers": [
{ "questionId": "q1", "title": "Your name", "value": "Ada Lovelace" },
{ "questionId": "q3", "title": "Department", "value": "Ops" }
]
},
"rule": { "id": "rule id", "name": "Zapier: new lead" }
}
eventvautsubmitted,approvedourejected; il figure aussi dans l'en-têteX-Skyfield-Eventresponse.respondentEmailvautnullsauf si le formulaire collecte les adresses e-mailanswers[].valueest toujours une chaîne ; les réponses à cases à cocher sont jointes par,rule.idetrule.nameidentifient la règle qui s'est déclenchée ;namevautnullsi la règle n'a pas de nom- Sur
approvedetrejected, un champ supplémentaireapproval: { "decision": "approved", "decidedBy": "Dana" }est inclus.decidedByest le nom saisi par l'approbateur sur la page de confirmation, à défaut l'adresse e-mail de l'approbateur, ounull.
version reste à 1 tant que la structure ci-dessus est stable. De nouveaux champs peuvent être ajoutés ; aucun n'est retiré ni renommé sans changement de version.
Vérifier la signature
Chaque requête porte un en-tête X-Skyfield-Signature : sha256=<hex>, le HMAC-SHA256 du corps brut de la requête, avec le secret de signature de votre règle comme clé. Vérifiez-le avant de faire confiance à une requête.

Le secret (whsec_...) est affiché une seule fois, juste après l'enregistrement qui donne à la règle sa première URL de webhook. Copiez-le à ce moment-là ; il ne peut plus être affiché ensuite. Remplacer l'URL plus tard conserve le même secret. Si vous le perdez, ouvrez la règle, cliquez sur Nouveau secret de signature et enregistrez : le nouveau secret est affiché une fois et l'ancien cesse immédiatement de fonctionner.
Calculez le HMAC sur les octets du corps exactement tels que reçus. Analyser puis resérialiser le JSON au préalable modifie les espaces et fait échouer la comparaison.
Node.js
import { createHmac, timingSafeEqual } from 'node:crypto'
// rawBody: string or Buffer of the request body, before any JSON parsing
function verify(rawBody, header, secret) {
const expected = 'sha256=' + createHmac('sha256', secret).update(rawBody).digest('hex')
const a = Buffer.from(expected)
const b = Buffer.from(header ?? '')
return a.length === b.length && timingSafeEqual(a, b)
}
// Express example: use express.raw() so req.body is the untouched bytes
app.post('/hook', express.raw({ type: 'application/json' }), (req, res) => {
if (!verify(req.body, req.get('X-Skyfield-Signature'), process.env.SKYFIELD_SECRET))
return res.status(401).end()
const payload = JSON.parse(req.body)
res.status(200).end()
})
Python
import hmac, hashlib
def verify(raw_body: bytes, header: str, secret: str) -> bool:
digest = hmac.new(secret.encode(), raw_body, hashlib.sha256).hexdigest()
return hmac.compare_digest("sha256=" + digest, header or "")
# Flask example
@app.post("/hook")
def hook():
if not verify(request.get_data(), request.headers.get("X-Skyfield-Signature"), SECRET):
return "", 401
payload = request.get_json()
return "", 200
Répondez avec n'importe quel statut 2xx. Le corps est ignoré.
Zapier, Make, n8n
Les trois acceptent un webhook JSON générique :
- Zapier : déclencheur Webhooks by Zapier, événement Catch Hook (ou Catch Raw Hook pour vérifier la signature vous-même). Collez dans la règle l'URL affichée par Zapier
- Make : ajoutez un module Webhooks, Custom webhook, et copiez son URL
- n8n : ajoutez un nœud Webhook, méthode POST, et utilisez son URL de production
Envoyez un test depuis la règle, puis mappez les champs response.answers dans la plateforme. Le payload d'exemple utilise des réponses fictives pour que chaque champ soit présent.
Livraison et limites
- La destination doit être joignable sur l'internet public en HTTPS. Les adresses privées et locales sont refusées à l'enregistrement
- Les redirections ne sont pas suivies : utilisez l'URL finale
- La destination a 5 secondes pour répondre. Un délai dépassé ou une réponse 5xx est réessayé une fois
- Une réponse 404 ou 410 signifie que la destination n'existe plus : la règle est mise en pause et vous recevez un seul e-mail. Collez une nouvelle URL sur la règle pour reprendre
- La page Historique liste chaque livraison avec le statut HTTP renvoyé par votre destination
- Une règle webhook en pause ou désactivée ne bloque pas les autres règles du formulaire
Bon à savoir
- Une règle webhook respecte Envoyer quand : une destination peut donc recevoir une décision d'approbation au lieu de chaque soumission. Voir Envoyer quand
- Pour n'envoyer que des réponses validées, réglez Envoyer quand de la règle sur Seulement après approbation et choisissez un approbateur. Voir Approbation. Le payload contient alors
approval.decision - Changer de canal… fait passer une règle webhook à E-mail ou à un canal de chat ; indiquez-y la nouvelle destination. Si vous revenez à Webhook, l'URL doit être collée à nouveau
- Les règles webhook nécessitent une licence active. L'essai gratuit compte. Voir ce qui nécessite une licence
