Saltar al contenido
Documentación

Webhooks salientes: payload y firma

Recibe las alertas e informes de AutoPSEO como JSON firmado en cualquier endpoint HTTPS: las cabeceras de la petición, los campos del cuerpo, los tipos de evento y cómo comprobar la firma.

Cuenta → Slack, Teams y Webhooks → Webhooks de salidaRequiere suscripción o prueba6 min de lectura

Un webhook saliente envía las alertas, los informes programados, los mensajes de prueba y los resúmenes de informes de AutoPSEO a un endpoint que tú gestionas, en forma de un POST JSON por mensaje firmado con HMAC-SHA256. Úsalo para alimentar Zapier, Make, n8n, una herramienta de incidencias o tu propio código; no hace falta ninguna cuenta de Slack ni de Teams. ¿Buscas el webhook que entrega artículos a tu sitio? Ese pertenece al motor de contenido: consulta la entrega de contenido.

Añadir un webhook

  1. En la sección Webhooks salientes, haz clic en Nuevo webhook.
  2. Ponle un Nombre y pega la URL del endpoint. Debe ser HTTPS público: se rechazan http sin cifrar, localhost, los nombres que terminan en .local o .internal, los hosts sin punto y las direcciones IP privadas o de enlace local.
  3. Copia el secreto de firma que aparece después de guardar. Solo se muestra esta vez.
  4. Haz clic en Enviar prueba para publicar un evento test y después asocia al webhook informes programados o alertas.

Cómo es una petición de webhook

Cada mensaje es un POST con estas cabeceras:

CabeceraValor
Content-Typeapplication/json
User-AgentAutoPSEO-Webhook/1.0
X-AutoPSEO-EventEl tipo de evento, por ejemplo traffic_drop
X-AutoPSEO-Signaturesha256= seguido de 64 caracteres hexadecimales en minúscula

Este es un ejemplo de alerta de caída de tráfico para una propiedad de dominio, de la ejecución de las 06:00 UTC del 12 de octubre de 2026, formateada para facilitar la lectura (en la red viaja como JSON compacto, y los valores de id y site_id son inventados):

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

Los campos de primer nivel son los mismos para todos los eventos:

CampoQué contiene
idUna cadena hexadecimal aleatoria de 32 caracteres, nueva en cada petición
event_typeQué ha ocurrido (consulta la sección siguiente)
severitycritical, high, medium o low para las alertas; info para informes, resúmenes y pruebas
site_idEl id de AutoPSEO de la propiedad, o null en las pruebas y en la propiedad de demostración
site_urlLa propiedad de Search Console, como sc-domain:example.com o https://www.example.com/, o null en las pruebas
occurred_atCuándo se construyó el mensaje, como marca de tiempo ISO 8601 en UTC
title, textEl titular y la frase de resumen que muestran Slack y Teams
urlEl informe en AutoPSEO, o null en las pruebas
payload.fieldsLos valores etiquetados que Slack muestra como campos y Teams como datos
payload.tablecolumns y rows para informes y resúmenes; en el resto de casos, null
sourceSiempre autopseo

Los ratios son fracciones: un change de -0.25 es una caída del 25 %, y un ctr de 0.034 es un 3,4 %.

Tipos de evento

event_typeSe envía cuandoClaves adicionales en payload
traffic_drop, traffic_spike, position_drop, ctr_drop, new_lost_rankings, anomaly, index_flip, rank_drop, audit_regressionSe activa una regla de alerta, según la programación o mediante Probar regladetector, window, range (las fechas, o null para index_flip, rank_drop y audit_regression), result
scheduled_reportSe envía un informe programado, según la programación o mediante Enviar ahorareportType (summary, queries, pages o rankings), range (fechas más un label), totals, previous
report_summaryAlguien usa Enviar a Slack en la página de un informeNinguna: las cifras están en fields y table
testAlguien hace clic en Enviar prueba en el webhooksample, siempre true

result repite lo que midió el detector: fired, metric, value, baseline, change (null cuando no hay nada con lo que comparar), severity y summary, además de z, la puntuación z modificada, en anomaly. totals y previous contienen clicks, impressions, ctr y position de las dos ventanas de un informe. Lo que mide cada detector se describe en Alertas.

Cómo verificar la firma

La firma es un HMAC-SHA256 de los bytes exactos que envió AutoPSEO, calculado con el secreto de firma del webhook y escrito como sha256= más hexadecimal en minúscula. Para comprobarla:

  1. Lee el cuerpo bruto de la petición antes de analizar el JSON. Si lo analizas y lo vuelves a serializar, los bytes pueden cambiar.
  2. Calcula el HMAC-SHA256 sobre esos bytes, usando el secreto como texto: la cadena de 64 caracteres tal como se muestra, sin decodificarla desde hexadecimal.
  3. Añade el prefijo sha256= y compara el resultado con la cabecera X-AutoPSEO-Signature en tiempo constante.
  4. Rechaza la petición si no coinciden. En caso contrario, responde enseguida con un estado 2xx y deja el trabajo lento para después.

Un receptor para Node.js sin dependencias:

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 comprobación de longitud va primero porque timingSafeEqual de Node lanza una excepción cuando los dos búferes tienen longitudes distintas.

Reglas de entrega

  • Cada mensaje tiene un solo intento con un tiempo de espera de 10 segundos. Cualquier respuesta que no sea 2xx cuenta como fallo y se conserva en el Historial de entregas con el código de estado y el principio del cuerpo de tu respuesta.
  • No se siguen las redirecciones. Una respuesta 3xx falla con una nota que indica que uses la URL final.
  • No se reintenta nada de forma programada. Una alerta fallida no se marca como enviada, de modo que su siguiente comprobación la evalúa de nuevo y la publica si sigue activa: a la mañana siguiente en la mayoría de los detectores, a la hora siguiente en los cambios de indexación. Un informe programado fallido no se reenvía dentro del mismo periodo, así que usa Enviar ahora después de arreglar el endpoint.
  • id se crea por petición, por lo que identifica una entrega y no un evento. Para deduplicar alertas, combina event_type, site_url y la fecha de occurred_at: una regla publica como máximo una vez por propiedad y día UTC, salvo que alguien ejecute Probar regla.

El secreto de firma

AutoPSEO muestra el secreto de firma una sola vez, al guardar el webhook, y la lista no vuelve a mostrarlo. Guárdalo de inmediato en la configuración de tu receptor, junto al endpoint que protege.

La URL se almacena cifrada y la lista solo muestra su host y los últimos caracteres. Al eliminar un webhook también se eliminan todas las reglas que publican en él. Si prefieres una tarjeta legible en un canal de Teams en lugar de JSON, usa Microsoft Teams.

Pon tu contenido SEO en piloto automático

Conecta Search Console y tu sitio. AutoPSEO lo analiza y planifica los primeros temas al instante. No necesitas tarjeta de crédito.