Webhooks sortants
Les webhooks envoient des événements Manisma vers un endpoint HTTPS public de votre organisation.
Configurer un endpoint
Ouvrez en tant qu’Admin Administration → Connecteurs, créez un endpoint et choisissez le nom, l’URL et les événements. Le signing secret s’affiche une seule fois. Conservez-le en sécurité. En cas de rotation, le nouveau secret s’applique dès l’enregistrement.
L’URL doit :
- utiliser HTTPS ;
- être publiquement accessible via DNS ;
- utiliser le port 443 ou 8443 ;
- ne pas contenir de nom d’utilisateur/mot de passe dans l’URL ;
- ne pas pointer vers localhost, une IP privée, link-local ou les métadonnées cloud.
Utilisez Test pour envoyer un ping avant d’activer de vrais événements.
Événements
| Événement | Déclencheur |
|---|---|
ping |
Test manuel de l’endpoint. |
client.created |
Client créé. |
client.updated |
Client modifié. |
job.created |
Ordre créé. |
job.planned |
Statut de l’ordre passé à planifié. |
job.completed |
Statut de l’ordre passé à terminé. |
job.cancelled |
Statut de l’ordre passé à annulé. |
approval.approved |
Le client a approuvé une proposition. |
approval.declined |
Le client a refusé une proposition. |
workorder.completed |
Données du bon de travail prêtes à facturer lors de la finalisation. |
Une modification d’un autre champ d’un ordre déjà terminé ne réenvoie pas job.completed ; c’est le statut lui-même qui doit changer.
Envelope et en-têtes
{
"event": "job.completed",
"version": 1,
"tenant_id": "tenant-uuid",
"occurred_at": "2026-07-13T09:15:00.000Z",
"data": {}
}
En-têtes :
X-Manisma-Event: nom de l’événement ;X-Manisma-Delivery: id stable de cette livraison logique ;X-Manisma-Signature:sha256=<hex HMAC-SHA256>sur le corps brut exact.
Vérifiez le HMAC avant l’analyse JSON et utilisez une comparaison à temps constant :
import { createHmac, timingSafeEqual } from 'node:crypto'
export function verify(rawBody, header, secret) {
if (!header?.startsWith('sha256=')) return false
const expected = createHmac('sha256', secret).update(rawBody).digest('hex')
const supplied = header.slice(7)
const a = Buffer.from(expected, 'hex')
const b = Buffer.from(supplied, 'hex')
return a.length === b.length && timingSafeEqual(a, b)
}
Payloads
Les événements client contiennent id, customer_number, name, client_type, email et phone. Les notes client internes sont absentes.
Les événements d’ordre contiennent l’id/numéro d’ordre, le titre, le statut, la priorité, le planning et des objets compacts pour le client, l’adresse de service et le technicien principal. Un ordre non assigné ou sans adresse utilise null.
Les événements d’approbation contiennent l’id d’approbation, job_id, statut, créneau choisi et heure de réponse. chosen_slot peut être une chaîne JSON ou un texte libre plus ancien ; analysez de manière défensive.
workorder.completed contient :
- ordre et client compacts ;
- la visite terminée la plus récente, si disponible ;
- matériaux utilisés avec SKU, prix de vente, quantité et montant de la ligne ;
- durée de travail ;
- total des matériaux en EUR.
Le prix du matériau est le prix de vente au moment de la construction du payload du webhook, pas nécessairement un prix figé historiquement.
Livraison et retries
Les webhooks sont at least once. Rendez votre récepteur idempotent sur X-Manisma-Delivery. Une réception réussie est toute réponse 2xx. Les redirections ne sont pas suivies et chaque tentative a un timeout de 10 secondes.
En cas d’erreur temporaire, il y a au maximum trois tentatives : immédiate, après 60 secondes, puis 300 secondes plus tard. Le même delivery-id est conservé. Les retries s’exécutent actuellement dans le processus de service et ne survivent pas à un redeploy ; vérifiez donc aussi le journal de livraison dans Connecteurs pour les lignes pending restées en suspens.
Enregistrez d’abord le delivery-id dans la même transaction que votre traitement, puis répondez rapidement avec 2xx. Déplacez le traitement lent vers votre propre file d’attente.