Salta al contenuto
Documentazione

Webhook in uscita: payload e firma

Ricevi gli avvisi e i report di AutoPSEO come JSON firmato su qualsiasi endpoint HTTPS: gli header della richiesta, i campi del body, i tipi di evento e come verificare la firma.

Account → Slack, Teams e webhook → Webhook in uscitaRichiede un abbonamento o una prova6 min di lettura

Un webhook in uscita invia gli avvisi, i report programmati, i messaggi di test e i riepiloghi dei report di AutoPSEO a un endpoint che gestisci tu, come una POST JSON per ogni messaggio, firmata con HMAC-SHA256. Usalo per alimentare Zapier, Make, n8n, uno strumento di gestione degli incidenti o il tuo codice; non serve alcun account Slack o Teams. Cerchi il webhook che consegna gli articoli al tuo sito? Appartiene al content engine: vedi consegna dei contenuti.

Aggiungere un webhook

  1. Nella sezione Webhook in uscita, fai clic su Nuovo webhook.
  2. Assegna un Nome e incolla l'URL dell'endpoint. Deve essere HTTPS pubblico: sono rifiutati http semplice, localhost, i nomi che terminano con .local o .internal, gli host senza punto e gli indirizzi IP privati o link-local.
  3. Copia il segreto di firma mostrato dopo il salvataggio. Viene visualizzato una sola volta.
  4. Fai clic su Invia test per inviare un evento test, quindi collega al webhook i report programmati o gli avvisi.

Come appare una richiesta webhook

Ogni messaggio è una POST con questi header:

HeaderValore
Content-Typeapplication/json
User-AgentAutoPSEO-Webhook/1.0
X-AutoPSEO-EventIl tipo di evento, ad esempio traffic_drop
X-AutoPSEO-Signaturesha256= seguito da 64 caratteri esadecimali minuscoli

Ecco un avviso di calo del traffico per una proprietà di dominio, relativo all'esecuzione delle 06:00 UTC del 12 ottobre 2026, formattato per la lettura (in transito è JSON compatto, e i valori di id e site_id sono inventati):

{
  "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"
}

I campi di primo livello sono gli stessi per ogni evento:

CampoCosa contiene
idUna stringa esadecimale casuale di 32 caratteri, nuova a ogni richiesta
event_typeCosa è successo (vedi la sezione successiva)
severitycritical, high, medium o low per gli avvisi; info per report, riepiloghi e test
site_idL'id che AutoPSEO assegna alla proprietà, oppure null per i test e la proprietà demo
site_urlLa proprietà di Search Console, ad esempio sc-domain:example.com o https://www.example.com/, oppure null per i test
occurred_atIl momento in cui il messaggio è stato costruito, come timestamp ISO 8601 in UTC
title, textIl titolo e la frase di riepilogo che Slack e Teams mostrano
urlIl report in AutoPSEO, oppure null per i test
payload.fieldsI valori con etichetta che Slack mostra come campi e Teams come fatti
payload.tablecolumns e rows per report e riepiloghi, altrimenti null
sourceSempre autopseo

I rapporti sono frazioni: un change di -0.25 indica un calo del 25% e un ctr di 0.034 indica il 3,4%.

Tipi di evento

event_typeInviato quandoChiavi aggiuntive in payload
traffic_drop, traffic_spike, position_drop, ctr_drop, new_lost_rankings, anomaly, index_flip, rank_drop, audit_regressionScatta una regola di avviso, a pianificazione o tramite Testa regoladetector, window, range (le date, oppure null per index_flip, rank_drop e audit_regression), result
scheduled_reportParte un report programmato, a pianificazione o tramite Invia orareportType (summary, queries, pages o rankings), range (date più un label), totals, previous
report_summaryQualcuno usa Invia a Slack nella pagina di un reportNessuna: i valori sono in fields e table
testQualcuno fa clic su Invia test sul webhooksample, sempre true

result riporta ciò che il rilevatore ha misurato: fired, metric, value, baseline, change (null quando non c'è nulla con cui confrontare), severity e summary, più z, lo z-score modificato, per anomaly. totals e previous contengono clicks, impressions, ctr e position per le due finestre di un report. Ciò che misura ciascun rilevatore è descritto in Avvisi.

Come verificare la firma

La firma è un HMAC-SHA256 dei byte esatti inviati da AutoPSEO, calcolato con il segreto di firma del webhook come chiave e scritto come sha256= più esadecimale minuscolo. Per verificarla:

  1. Leggi il body grezzo della richiesta prima di qualsiasi parsing JSON. Analizzarlo e serializzarlo di nuovo può modificare i byte.
  2. Calcola l'HMAC-SHA256 su quei byte, usando il segreto come testo: la stringa di 64 caratteri esattamente come mostrata, non decodificata da esadecimale.
  3. Anteponi sha256= e confronta il risultato con l'header X-AutoPSEO-Signature in tempo costante.
  4. Rifiuta la richiesta se non corrispondono. Altrimenti rispondi subito con uno stato 2xx ed esegui in seguito le operazioni più lente.

Un ricevitore per Node.js senza dipendenze:

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);

Il controllo della lunghezza viene per primo perché timingSafeEqual di Node genera un errore quando i due buffer hanno lunghezze diverse.

Regole di consegna

  • Ogni messaggio ha un solo tentativo con un timeout di 10 secondi. Qualsiasi risposta diversa da 2xx conta come errore e viene conservata nella Cronologia consegne con il codice di stato e l'inizio del body della risposta.
  • I reindirizzamenti non vengono seguiti. Una risposta 3xx fallisce con l'indicazione di usare l'URL finale.
  • Nulla viene ritentato in automatico. Un avviso non riuscito non viene contrassegnato come inviato, quindi al controllo successivo viene valutato di nuovo e pubblicato se scatta ancora: la mattina seguente per la maggior parte dei rilevatori, l'ora successiva per gli index flip. Un report programmato non riuscito non viene rinviato nello stesso periodo, quindi usa Invia ora dopo aver sistemato l'endpoint.
  • id viene creato per ogni richiesta, quindi identifica una consegna e non un evento. Per deduplicare gli avvisi, combina event_type, site_url e la data di occurred_at: una regola pubblica al massimo una volta per proprietà per giorno UTC, a meno che qualcuno non esegua Testa regola.

Il segreto di firma

AutoPSEO mostra il segreto di firma una sola volta, quando salvi il webhook, e l'elenco non lo mostra più. Conservalo subito nella configurazione del tuo ricevitore, insieme all'endpoint che protegge.

L'URL stesso è memorizzato in forma cifrata, e l'elenco ne mostra solo l'host e gli ultimi caratteri. Eliminare un webhook elimina anche tutte le regole che pubblicano su di esso. Per una scheda leggibile in un canale Teams invece del JSON, usa Microsoft Teams.

Metti i tuoi contenuti SEO in pilota automatico

Collega Search Console e il tuo sito. AutoPSEO lo analizza e pianifica subito i primi argomenti. Nessuna carta di credito richiesta.