Aller au contenu
Documentation

Webhooks sortants : payload et signature

Recevez les alertes et les rapports d'AutoPSEO sous forme de JSON signé sur n'importe quel endpoint HTTPS : en-têtes de requête, champs du corps, types d'événements et vérification de la signature.

Compte → Slack, Teams et Webhooks → Webhooks sortantsNécessite un abonnement ou un essai6 min de lecture

Un webhook sortant envoie les alertes, les rapports programmés, les messages de test et les résumés de rapport d'AutoPSEO vers un endpoint que vous hébergez, sous la forme d'un POST JSON par message, signé avec HMAC-SHA256. Utilisez-le pour alimenter Zapier, Make, n8n, un outil de gestion d'incidents ou votre propre code ; aucun compte Slack ou Teams n'est nécessaire. Vous cherchez le webhook qui livre des articles sur votre site ? Il relève du moteur de contenu : consultez la page livraison du contenu.

Ajouter un webhook

  1. Dans la section Webhooks sortants, cliquez sur Nouveau webhook.
  2. Donnez-lui un Nom et collez l'URL de l'endpoint. Elle doit être en HTTPS public : le simple http, localhost, les noms se terminant par .local ou .internal, les hôtes sans point et les adresses IP privées ou link-local sont refusés.
  3. Copiez le secret de signature affiché après l'enregistrement. Il n'apparaît qu'une seule fois.
  4. Cliquez sur Envoyer un test pour poster un événement test, puis rattachez des rapports programmés ou des alertes au webhook.

À quoi ressemble une requête de webhook

Chaque message est un POST accompagné de ces en-têtes :

En-têteValeur
Content-Typeapplication/json
User-AgentAutoPSEO-Webhook/1.0
X-AutoPSEO-EventLe type d'événement, par exemple traffic_drop
X-AutoPSEO-Signaturesha256= suivi de 64 caractères hexadécimaux en minuscules

Voici une alerte de baisse de trafic pour une propriété de domaine, issue de l'exécution de 06:00 UTC le 12 octobre 2026, mise en forme pour la lecture (sur le réseau, il s'agit d'un JSON compact, et les valeurs id et site_id sont fictives) :

{
  "id": "9b2e61f04c3a4d7e8f15a0b6c2d39e47",
  "event_type": "traffic_drop",
  "severity": "high",
  "site_id": "4f0c1e9a2b7d4c58",
  "site_url": "sc-domain:example.com",
  "occurred_at": "2026-10-12T06:00:04.183Z",
  "title": "Traffic drop: example.com",
  "text": "Clicks 1,500 vs 2,000 in the previous window (-25.0%).",
  "url": "https://app.autopseo.com/property/sc-domain%3Aexample.com",
  "payload": {
    "fields": [
      { "label": "Metric", "value": "clicks" },
      { "label": "Current", "value": "1,500" },
      { "label": "Baseline", "value": "2,000" },
      { "label": "Window", "value": "7 days (2026-10-05 → 2026-10-11 vs 2026-09-28 → 2026-10-04)" },
      { "label": "Change", "value": "-25.0%" }
    ],
    "table": null,
    "detector": "traffic_drop",
    "window": 7,
    "range": { "start": "2026-10-05", "end": "2026-10-11", "compStart": "2026-09-28", "compEnd": "2026-10-04" },
    "result": {
      "fired": true,
      "metric": "clicks",
      "value": 1500,
      "baseline": 2000,
      "change": -0.25,
      "severity": "high",
      "summary": "Clicks 1,500 vs 2,000 in the previous window (-25.0%)."
    }
  },
  "source": "autopseo"
}

Les champs de premier niveau sont identiques pour tous les événements :

ChampContenu
idUne chaîne hexadécimale aléatoire de 32 caractères, nouvelle à chaque requête
event_typeCe qui s'est produit (voir la section suivante)
severitycritical, high, medium ou low pour les alertes ; info pour les rapports, les résumés et les tests
site_idL'identifiant AutoPSEO de la propriété, ou null pour les tests et la propriété de démonstration
site_urlLa propriété Search Console, par exemple sc-domain:example.com ou https://www.example.com/, ou null pour les tests
occurred_atLe moment de construction du message, sous forme d'horodatage ISO 8601 en UTC
title, textLe titre et la phrase de synthèse affichés par Slack et Teams
urlLe rapport dans AutoPSEO, ou null pour les tests
payload.fieldsLes valeurs étiquetées que Slack affiche comme champs et Teams comme faits
payload.tablecolumns et rows pour les rapports et les résumés, sinon null
sourceToujours autopseo

Les ratios sont des fractions : un change de -0.25 correspond à une baisse de 25 %, et un ctr de 0.034 à 3,4 %.

Types d'événements

event_typeEnvoyé quandClés supplémentaires dans payload
traffic_drop, traffic_spike, position_drop, ctr_drop, new_lost_rankings, anomaly, index_flip, rank_drop, audit_regressionUne règle d'alerte se déclenche, selon la planification ou via Tester la règledetector, window, range (les dates, ou null pour index_flip, rank_drop et audit_regression), result
scheduled_reportUn rapport programmé part, selon la planification ou via Envoyer maintenantreportType (summary, queries, pages ou rankings), range (les dates plus un label), totals, previous
report_summaryQuelqu'un utilise Envoyer vers Slack sur une page de rapportAucune : les chiffres figurent dans fields et table
testQuelqu'un clique sur Envoyer un test pour le webhooksample, toujours à true

result reprend ce que le détecteur a mesuré : fired, metric, value, baseline, change (null quand il n'y a rien à comparer), severity et summary, ainsi que z, le z-score modifié, pour anomaly. totals et previous contiennent clicks, impressions, ctr et position pour les deux fenêtres d'un rapport. Ce que mesure chaque détecteur est décrit dans la page Alertes.

Comment vérifier la signature

La signature est un HMAC-SHA256 des octets exacts envoyés par AutoPSEO, calculé avec le secret de signature du webhook et écrit sous la forme sha256= suivi de l'hexadécimal en minuscules. Pour la vérifier :

  1. Lisez le corps brut de la requête avant tout parsing JSON. Analyser puis resérialiser le contenu peut modifier les octets.
  2. Calculez le HMAC-SHA256 de ces octets, en utilisant le secret comme texte : la chaîne de 64 caractères telle qu'elle est affichée, sans la décoder depuis l'hexadécimal.
  3. Ajoutez le préfixe sha256= et comparez le résultat à l'en-tête X-AutoPSEO-Signature en temps constant.
  4. Rejetez la requête si les valeurs diffèrent. Sinon, répondez immédiatement par un statut 2xx et effectuez le traitement lent ensuite.

Un récepteur pour Node.js, sans aucune dépendance :

import { createServer } from 'node:http';
import { createHmac, timingSafeEqual } from 'node:crypto';

const secret = process.env.AUTOPSEO_WEBHOOK_SECRET;

createServer((req, res) => {
  const chunks = [];
  req.on('data', (chunk) => chunks.push(chunk));
  req.on('end', () => {
    const raw = Buffer.concat(chunks);
    const expected = Buffer.from('sha256=' + createHmac('sha256', secret).update(raw).digest('hex'));
    const received = Buffer.from(String(req.headers['x-autopseo-signature'] || ''));
    if (received.length !== expected.length || !timingSafeEqual(received, expected)) {
      res.writeHead(401).end();
      return;
    }
    res.writeHead(204).end();
    const event = JSON.parse(raw.toString('utf8'));
    console.log(event.event_type, event.severity, event.site_url);
  });
}).listen(8080);

La vérification de la longueur passe en premier, car la fonction timingSafeEqual de Node lève une exception lorsque les deux buffers n'ont pas la même longueur.

Règles de livraison

  • Chaque message fait l'objet d'une seule tentative, avec un délai d'expiration de 10 secondes. Toute réponse autre que 2xx est considérée comme un échec et est conservée dans l'Historique des envois avec le code de statut et le début du corps de votre réponse.
  • Les redirections ne sont pas suivies. Une réponse 3xx échoue avec une note invitant à utiliser l'URL finale.
  • Aucun nouvel essai n'est programmé. Une alerte en échec n'est pas marquée comme envoyée : à la vérification suivante, elle est réévaluée et publiée si elle se déclenche toujours, le lendemain matin pour la plupart des détecteurs, l'heure suivante pour les index flips. Un rapport programmé en échec n'est pas renvoyé au cours de la même période : utilisez Envoyer maintenant une fois l'endpoint corrigé.
  • id est créé à chaque requête ; il identifie donc un envoi et non un événement. Pour dédupliquer les alertes, combinez event_type, site_url et la date de occurred_at : une règle publie au plus une fois par propriété et par jour UTC, sauf si quelqu'un lance Tester la règle.

Le secret de signature

AutoPSEO n'affiche le secret de signature qu'une seule fois, à l'enregistrement du webhook, et la liste ne le montre plus jamais ensuite. Conservez-le immédiatement dans la configuration de votre récepteur, à côté de l'endpoint qu'il protège.

L'URL elle-même est stockée chiffrée, et la liste n'en montre que l'hôte et les derniers caractères. Supprimer un webhook supprime aussi toutes les règles qui publient vers lui. Pour obtenir une carte lisible dans un canal Teams plutôt que du JSON, utilisez Microsoft Teams.

Mettez votre contenu SEO en pilote automatique

Connectez Search Console et votre site. AutoPSEO l'analyse et planifie aussitôt les premiers sujets. Sans carte bancaire.