Un webhook lance une routine quand un autre service (Zapier, Make, n8n, un script, votre propre serveur) envoie une requête signée à son adresse. Le corps JSON de la requête est transmis à la routine avec son prompt, comme une donnée. La requête répond tout de suite ; l’exécution se fait ensuite, et son résultat arrive dans la conversation de la routine.
Créer un déclencheurLien vers la section Créer un déclencheur
- Ouvrez la routine dans « Routines », puis l’onglet « Webhooks ».
- Cliquez sur « Créer un déclencheur webhook ». Le « Nom » est facultatif : il sert à distinguer vos déclencheurs, par exemple « Zapier nouveaux prospects ».
- Copiez l’« URL du webhook » et la « Clé de signature ».
- Cliquez sur « J’ai enregistré la clé ».
« Voir un exemple d’appel » affiche une commande prête à copier avec votre adresse et votre clé.
Chaque routine peut avoir jusqu’à 5 déclencheurs. L’onglet « Webhooks » indique combien d’appels chaque déclencheur accepte par minute et par jour : le nombre par jour dépend du forfait du workspace (voir les formules).
Référence du point d’accèsLien vers la section Référence du point d’accès
POST /api/v1/routines/hooks/{identifiant} Lien vers la section POST /api/v1/routines/hooks/{identifiant}
Lance une exécution de la routine liée au déclencheur.
| Élément | Valeur |
|---|---|
| Adresse complète | https://, donnée par l’onglet « Webhooks ». Elle ne contient aucun secret. |
| Authentification | La signature HMAC de la requête. Aucun jeton de session ni aucune clé d’API n’est utilisé. |
| Portée | Une seule routine : celle du déclencheur. Le propriétaire de la routine doit être membre actif de son workspace, et le forfait du workspace doit inclure les routines. |
| Corps | Du JSON, 64 Ko au plus. Un corps vide vaut {}. |
ParamètresLien vers la section Paramètres
| Nom | Emplacement | Type | Obligatoire | Description |
|---|---|---|---|---|
identifiant | Chemin | Chaîne | Oui | L’identifiant public du déclencheur, de 16 à 64 caractères (lettres, chiffres, _ et -). |
Content-Type | En-tête | Chaîne | Oui | application/, ou un type application/. |
X-Moon-Timestamp | En-tête | Chaîne | Oui | L’heure de l’appel en secondes Unix, en chiffres seulement. Elle doit être à moins de 5 minutes de l’heure du serveur, dans un sens ou dans l’autre. |
X-Moon-Signature | En-tête | Chaîne | Oui | v1= suivi de la signature en hexadécimal minuscule (64 caractères). Plusieurs signatures peuvent être séparées par des virgules. |
| Corps | Corps | Objet JSON | Non | Les données de l’événement, transmises à la routine. |
RéponseLien vers la section Réponse
Une requête acceptée répond 202 avant que la routine ne s’exécute :
{"run_id": "4b0c1f0e-2a7d-4c41-9e3b-6f1d2c8a5b90", "status": "queued"}| Champ | Type | Description |
|---|---|---|
run_id | Chaîne | L’identifiant de l’exécution, visible dans l’onglet « Historique » de la routine. |
status | Chaîne | Toujours queued : l’exécution attend son tour. |
L’exécution apparaît dans l’onglet « Historique » de la routine avec le déclencheur « Webhook ». Gardez l’horloge de la machine qui envoie à l’heure.
La signatureLien vers la section La signature
La signature est un HMAC-SHA256 :
- la clé est la clé de signature, telle qu’affichée (elle commence par
mwk_) ; - le message est l’horodatage, un point, puis le corps brut, exactement les octets envoyés ;
- le résultat est écrit en hexadécimal minuscule, 64 caractères.
<X-Moon-Timestamp>.<corps brut>Pour vérifier votre calcul, avec ces valeurs d’exemple :
| Élément | Valeur |
|---|---|
| Clé | mwk_exempleDeCle |
X-Moon-Timestamp | 1762300800 |
| Corps | {"event":"new_lead", |
| Signature attendue | 0d61b9fd29504eb3bd85a2e00361373c8f786822ddb73162bb825ca45abfcb67 |
L’en-tête X-Moon-Signature peut contenir jusqu’à 5 signatures séparées par des virgules (v1=…,v1=…) : la requête est acceptée si l’une d’elles correspond. Une signature sans le préfixe v1= est acceptée aussi.
ExemplesLien vers la section Exemples
Remplacez l’adresse et la clé par celles de votre déclencheur.
KEY='mwk_votre_cle'
URL='https://chat.realmoon.ai/api/v1/routines/hooks/votre_identifiant'
BODY='{"event":"new_lead","id":"evt_123"}'
TS=$(date +%s)
SIG=$(printf '%s.%s' "$TS" "$BODY" | openssl dgst -sha256 -hmac "$KEY" -hex | sed 's/^.* //')
curl -sS -X POST "$URL" \
-H 'Content-Type: application/json' \
-H "X-Moon-Timestamp: $TS" \
-H "X-Moon-Signature: v1=$SIG" \
--data-binary "$BODY"import hashlib, hmac, json, time, requests
key = "mwk_votre_cle"
url = "https://chat.realmoon.ai/api/v1/routines/hooks/votre_identifiant"
body = json.dumps({"event": "new_lead", "id": "evt_123"}).encode()
ts = str(int(time.time()))
sig = hmac.new(key.encode(), ts.encode() + b"." + body, hashlib.sha256).hexdigest()
r = requests.post(url, data=body, headers={
"Content-Type": "application/json",
"X-Moon-Timestamp": ts,
"X-Moon-Signature": f"v1={sig}",
})
print(r.status_code, r.json())import { createHmac } from 'node:crypto';
const key = 'mwk_votre_cle';
const url = 'https://chat.realmoon.ai/api/v1/routines/hooks/votre_identifiant';
const body = JSON.stringify({ event: 'new_lead', id: 'evt_123' });
const ts = Math.floor(Date.now() / 1000).toString();
const sig = createHmac('sha256', key).update(`${ts}.${body}`).digest('hex');
const res = await fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Moon-Timestamp': ts,
'X-Moon-Signature': `v1=${sig}`
},
body
});
console.log(res.status, await res.json());En Python, passez le corps déjà encodé dans data= (et non json=), pour envoyer les octets signés. L’exemple JavaScript tourne avec Node.js 18 ou plus récent.
Dans Zapier, Make ou n8n, utilisez une étape de code ou de requête HTTP qui calcule la signature sur le corps exact, puis l’envoie avec les deux en-têtes.
ErreursLien vers la section Erreurs
Le corps d’une erreur a la forme {"detail": . Le détail est soit un texte, soit un objet {"code": .
| Statut | Code ou texte | Cause |
|---|---|---|
400 | stale_timestamp | X-Moon-Timestamp est à plus de 5 minutes de l’heure du serveur. |
400 | invalid_json | Le corps n’est pas du JSON valide. |
403 | feature_scheduled_routines | Le forfait du workspace n’inclut pas les routines. |
404 | « Introuvable. » | Adresse inconnue, déclencheur désactivé ou supprimé, signature absente ou fausse, horodatage absent ou mal formé, routine en pause ou supprimée, ou propriétaire qui ne peut plus l’exécuter. |
409 | replayed | Cette requête a déjà été reçue (même signature). |
413 | « Corps de requête trop volumineux (64 Ko au plus). » | Le corps dépasse 64 Ko. |
415 | « Le corps doit être du JSON (application/json). » | Content-Type n’est pas un type JSON. |
429 | rate_limited, « Limite de ce déclencheur atteinte. » | Le déclencheur a reçu trop d’appels dans la minute ou dans la journée. |
429 | rate_limited, « Trop de requêtes. » | Trop de requêtes refusées depuis votre adresse (plus de 60 par minute). |
429 | queue_full | 20 exécutions attendent déjà pour cette routine. |
503 | « Service momentanément indisponible. Réessayez dans un instant. » | Panne passagère. |
Exemples de corps :
{"detail": "Introuvable."}{"detail": {"code": "rate_limited", "message": "Limite de ce déclencheur atteinte."}}Le même 404 répond pour toutes les causes listées, pour ne rien révéler de l’existence d’un déclencheur. Vérifiez d’abord l’adresse, la clé et le calcul de la signature.
Renvoyer une requêteLien vers la section Renvoyer une requête
- Une requête refusée par
429,403ou503ne compte pas dans les limites du déclencheur. Vous pouvez la renvoyer telle quelle tant que son horodatage a moins de 5 minutes, ou la signer de nouveau avec une heure récente. - Deux requêtes identiques (même corps, même seconde) ont la même signature : la seconde reçoit
409. Ajoutez un identifiant d’événement unique au corps, par exemple"id":."evt_123" - Une requête acceptée n’est jamais exécutée deux fois, même renvoyée.
Ce que fait la routineLien vers la section Ce que fait la routine
La routine reçoit son prompt, suivi du corps de la requête présenté comme des données envoyées par un service externe. L’IA s’en sert comme matière pour la tâche, sans suivre les instructions qu’il pourrait contenir. Le corps passe par Moon Blur comme le reste de la requête.
Une exécution lancée par un webhook :
- n’agit jamais dans vos connecteurs (aucun e-mail envoyé, aucun message publié), même si la routine a l’option « Autoriser les actions » ;
- n’ouvre pas de page web, n’exécute pas de code, ne génère ni image ni vidéo ;
- ne crée pas de lien public vers vos fichiers et n’en joint pas à un message ;
- peut lire vos connecteurs et chercher sur le web ;
- n’est pas relancée automatiquement en cas d’erreur ;
- compte dans votre limite d’utilisation comme une exécution normale.
Le prompt et la réponse sont marqués comme contenant un contenu extérieur : rien de distant ne se charge dans la réponse sans votre clic. Tant que ce message reste dans la conversation, les tours suivants gardent les mêmes précautions : chaque action dans vos outils demande votre validation.
Gérer les déclencheursLien vers la section Gérer les déclencheurs
| Action | Effet |
|---|---|
| « Activer » suivi du nom (interrupteur) | Désactivé, le déclencheur répond 404. |
| « Renommer » | Change le nom affiché. |
| « Renouveler la clé de signature » | Donne une nouvelle clé. L’ancienne cesse de fonctionner immédiatement. |
| « Supprimer » | Les requêtes envoyées à son adresse sont refusées. Irréversible. |
Désactiver un déclencheur, renouveler sa clé ou le supprimer annule aussi ses exécutions en file qui n’ont pas encore démarré. La liste montre pour chaque déclencheur les « Appels reçus » et la date du dernier appel. Supprimer la routine supprime ses déclencheurs.