Gurren API

Webhooks

Recevoir des notifications HTTP quand des événements se produisent sur vos automations et pipelines.

Webhooks

Les webhooks vous permettent de recevoir des notifications HTTP en temps réel quand des événements se produisent dans Gurren. Configurez une URL cible et choisissez les événements qui vous intéressent.

Les endpoints webhooks nécessitent un JWT Bearer token (pas une API key). Gérez vos webhooks depuis le dashboard ou via les endpoints ci-dessous.

Créer un webhook

POST /webhooks
curl -X POST https://api.gurren.leandre.io/webhooks \
  -H "Authorization: Bearer <jwt_token>" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Notification Slack",
    "url": "https://example.com/webhook",
    "events": ["automation.completed", "automation.failed"]
  }'

Body :

ParamètreTypeRequisDescription
namestringouiNom du webhook
urlstringouiURL cible (HTTPS recommandé)
eventsstring[]ouiListe des événements souscrits

Réponse :

{
  "_id": "665a...",
  "name": "Notification Slack",
  "url": "https://example.com/webhook",
  "events": ["automation.completed", "automation.failed"],
  "isActive": true,
  "secret": "whsec_a1b2c3d4e5f6...",
  "failureCount": 0,
  "lastTriggeredAt": null,
  "lastStatus": null,
  "createdAt": "2024-06-01T10:00:00.000Z"
}

Important : Le champ secret n'est retourné qu'à la création. Conservez-le pour vérifier les signatures.


Lister les webhooks

GET /webhooks
curl https://api.gurren.leandre.io/webhooks \
  -H "Authorization: Bearer <jwt_token>"

Détail d'un webhook

GET /webhooks/:id

Mettre à jour un webhook

PATCH /webhooks/:id
curl -X PATCH https://api.gurren.leandre.io/webhooks/665a... \
  -H "Authorization: Bearer <jwt_token>" \
  -H "Content-Type: application/json" \
  -d '{
    "events": ["automation.completed", "pipeline.completed"],
    "isActive": true
  }'

Champs modifiables : name, url, events, isActive, secret


Supprimer un webhook

DELETE /webhooks/:id

Tester un webhook

POST /webhooks/:id/test

Envoie un événement de test à l'URL configurée pour vérifier que votre endpoint fonctionne.

curl -X POST https://api.gurren.leandre.io/webhooks/665a.../test \
  -H "Authorization: Bearer <jwt_token>"

Payload envoyé à votre URL :

{
  "event": "webhook.test",
  "timestamp": "2024-06-01T10:00:00.000Z",
  "data": {
    "message": "This is a test event from Gurren",
    "webhookId": "665a..."
  }
}

Réponse API :

{
  "status": 200
}

Le champ status contient le code HTTP retourné par votre endpoint.


Événements disponibles

ÉvénementDescription
automation.completedUne automation s'est terminée avec succès
automation.failedUne automation a échoué
pipeline.completedUn pipeline s'est terminé avec succès
pipeline.failedUn pipeline a échoué
execution.startedUne exécution a démarré
execution.selfheal.startedL'IA commence à réparer une étape cassée
execution.selfheal.succeededUne étape a été réparée (sélecteur relocalisé/agi)
execution.selfheal.failedLa réparation d'une étape a échoué
intent.receivedUn intent a été accepté (job créé)
intent.resolvedUne automation existante a matché l'intent
intent.generation.startedAucune correspondance → génération lancée
intent.generation.completedNouvelle automation générée (à valider)
intent.generation.failedLa génération a échoué
intent.completedÉtat final de l'intent (outcome: executed/generated)
intent.failedL'intent a échoué
job.enqueuedUn job a été ajouté à la file d'attente
job.completedUn job en file d'attente s'est terminé
job.failedUn job en file d'attente a échoué

Format des payloads

Chaque notification webhook est envoyée en POST. Le contenu varie selon l'événement.

automation.completed / automation.failed

{
  "event": "automation.completed",
  "timestamp": "2024-06-01T10:01:30.000Z",
  "data": {
    "executionId": "777b2c3d4e5f6a7b8c9d0eee",
    "sessionId": "999c3d4e5f6a7b8c9d0e1fff",
    "automationId": "665a1b2c3d4e5f6a7b8c9d0e",
    "automationName": "Login et extraction",
    "status": "completed",
    "error": null,
    "extractedData": {
      "email": "john@example.com",
      "prix": "29.99€"
    },
    "selfHeal": {
      "occurred": true,
      "count": 1,
      "healedActions": [
        { "actionName": "Accepter les cookies", "newSelector": "button.cookie-accept" }
      ]
    }
  }
}

Le bloc selfHeal indique si la run s'est auto-réparée et quels sélecteurs ont été persistés sur l'automation (donc ce qui a changé). Le détail événement par événement est disponible via les webhooks execution.selfheal.* et dans selfHealEvents de GET /api/v1/executions/:id.

Payload des execution.selfheal.* (dans data) : { jobId, executionId, automationId, actionName, newSelector?, message }.

Enveloppe uniforme : tous les webhooks (events ET job.*) ont la même forme { event, timestamp, data }. Lisez toujours les champs sous data (ex. data.jobId). Quand un job est à l'origine, data.jobId est présent dès le premier événement.

ChampTypeDescription
executionIdstringID de l'exécution
sessionIdstring | nullID de la session sauvegardée à la fin du run (état final, ex. connecté). À repasser comme sessionId du run suivant pour chaîner la session. null si aucune session n'a été sauvegardée
automationIdstringID de l'automation
automationNamestringNom de l'automation
statusstringcompleted ou failed
errorstring | nullMessage d'erreur (null si succès)
extractedDataobjectDonnées extraites par les actions extractText

pipeline.completed / pipeline.failed

{
  "event": "pipeline.completed",
  "timestamp": "2024-06-01T10:05:00.000Z",
  "data": {
    "pipelineId": "888a1b2c3d4e5f6a7b8c9d0e",
    "pipelineName": "Pipeline inscription",
    "status": "completed",
    "extractedData": {}
  }
}
ChampTypeDescription
pipelineIdstringID du pipeline
pipelineNamestringNom du pipeline
statusstringcompleted, failed, ou partial_failed
extractedDataobjectDonnées extraites agrégées

execution.started

{
  "event": "execution.started",
  "timestamp": "2024-06-01T10:00:01.000Z",
  "data": {
    "executionId": "777b2c3d4e5f6a7b8c9d0eee",
    "automationId": "665a1b2c3d4e5f6a7b8c9d0e",
    "status": "running"
  }
}

job.enqueued

{
  "event": "job.enqueued",
  "timestamp": "2024-06-01T10:00:00.000Z",
  "data": {
    "jobId": "aaa1b2c3d4e5f6a7b8c9d0e1",
    "type": "automation",
    "targetId": "665a1b2c3d4e5f6a7b8c9d0e",
    "status": "pending"
  }
}
ChampTypeDescription
jobIdstringID du job
typestringautomation ou pipeline
targetIdstringID de l'automation ou du pipeline
statusstringToujours pending

job.completed / job.failed

{
  "event": "job.completed",
  "timestamp": "2024-06-01T10:01:30.000Z",
  "data": {
    "jobId": "aaa1b2c3d4e5f6a7b8c9d0e1",
    "type": "automation",
    "targetId": "665a1b2c3d4e5f6a7b8c9d0e",
    "executionId": "777b2c3d4e5f6a7b8c9d0eee",
    "sessionId": "999c3d4e5f6a7b8c9d0e1fff",
    "status": "completed",
    "result": { "status": "completed" },
    "error": null,
    "completedAt": "2024-06-01T10:01:30.000Z"
  }
}
ChampTypeDescription
jobIdstringID du job
typestringautomation ou pipeline
targetIdstringID de l'automation ou du pipeline
executionIdstring | nullID de l'exécution associée
sessionIdstring | nullID de la session sauvegardée à la fin du run, pour chaîner la session au run suivant (null si aucune)
statusstringcompleted ou failed
resultobject | nullRésultat du job
errorstring | nullMessage d'erreur
completedAtstring | nullDate de fin au format ISO

Headers envoyés

HeaderDescription
Content-Typeapplication/json
User-AgentGurren-Webhook/1.0
X-Gurren-EventNom de l'événement (ex: automation.completed)
X-Gurren-SignatureSignature HMAC SHA-256 du body

Vérification de signature

Chaque requête est signée avec le secret de votre webhook. Vérifiez la signature pour vous assurer que la requête provient bien de Gurren.

La signature est au format sha256=<hex_hmac>.

Webhooks de job (livrés au webhookUrl fourni à /enqueue) : ils sont signés avec le secret du webhook enregistré pour cette même URL. Enregistrez donc un webhook (même URL, secret voulu) pour que les job.* arrivent signés et passent votre vérification. (À défaut, WEBHOOK_SIGNING_SECRET côté serveur sert de repli.)

Exemple en Node.js

const crypto = require('crypto');
 
function verifySignature(secret, body, signature) {
  const expected = 'sha256=' + crypto
    .createHmac('sha256', secret)
    .update(body)
    .digest('hex');
 
  return crypto.timingSafeEqual(
    Buffer.from(expected),
    Buffer.from(signature)
  );
}
 
// Dans votre handler Express
app.post('/webhook', (req, res) => {
  const signature = req.headers['x-gurren-signature'];
  const body = JSON.stringify(req.body);
 
  if (!verifySignature('whsec_votre_secret', body, signature)) {
    return res.status(401).send('Invalid signature');
  }
 
  // Traiter l'événement
  console.log(req.body.event, req.body.data);
  res.status(200).send('OK');
});

Retry et fiabilité

En cas d'échec de livraison (timeout, erreur HTTP 5xx), Gurren retente automatiquement avec un backoff exponentiel :

TentativeDélai
15 secondes
230 secondes
32 minutes
410 minutes
530 minutes

Après 5 tentatives échouées, la livraison est abandonnée. Le compteur failureCount du webhook est incrémenté à chaque échec et remis à zéro après une livraison réussie.

Consultez le champ failureCount et lastStatus dans le détail du webhook pour diagnostiquer les problèmes.

On this page