Ir para o conteúdo
Documentação

Webhooks de saída: payload e assinatura

Receba alertas e relatórios do AutoPSEO como JSON assinado em qualquer endpoint HTTPS: os cabeçalhos da requisição, os campos do corpo, os tipos de evento e como verificar a assinatura.

Conta → Slack, Teams e Webhooks → Webhooks de saídaRequer assinatura ou período de teste6 min de leitura

Um webhook de saída envia os alertas, os relatórios agendados, as mensagens de teste e os resumos de relatórios do AutoPSEO para um endpoint que você mantém, como um POST JSON por mensagem, assinado com HMAC-SHA256. Use-o para alimentar Zapier, Make, n8n, uma ferramenta de incidentes ou o seu próprio código; não é necessária nenhuma conta do Slack ou do Teams. Procura o webhook que entrega artigos ao seu site? Esse pertence ao mecanismo de conteúdo: veja entrega de conteúdo.

Adicionar um webhook

  1. Na seção Outbound webhooks, clique em New webhook.
  2. Dê um Name ao webhook e cole a URL do endpoint. Ela deve ser HTTPS público: http simples, localhost, nomes terminados em .local ou .internal, hosts sem ponto e endereços IP privados ou link-local são recusados.
  3. Copie o signing secret exibido depois de salvar. Ele é mostrado apenas desta vez.
  4. Clique em Send test para enviar um evento test e, em seguida, associe ao webhook os relatórios agendados ou os alertas.

Como é uma requisição de webhook

Toda mensagem é um POST com estes cabeçalhos:

CabeçalhoValor
Content-Typeapplication/json
User-AgentAutoPSEO-Webhook/1.0
X-AutoPSEO-EventO tipo de evento, por exemplo traffic_drop
X-AutoPSEO-Signaturesha256= seguido de 64 caracteres hexadecimais em minúsculas

Veja um alerta de queda de tráfego para uma propriedade de domínio, da execução das 06:00 UTC de 12 de outubro de 2026, formatado para leitura (na transmissão real, o JSON é compacto, e os valores de id e site_id são fictícios):

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

Os campos de nível superior são os mesmos em todos os eventos:

CampoO que contém
idUma string hexadecimal aleatória de 32 caracteres, nova a cada requisição
event_typeO que aconteceu (veja a próxima seção)
severitycritical, high, medium ou low para alertas; info para relatórios, resumos e testes
site_idO id da propriedade no AutoPSEO, ou null para testes e para a propriedade de demonstração
site_urlA propriedade do Search Console, como sc-domain:example.com ou https://www.example.com/, ou null para testes
occurred_atQuando a mensagem foi montada, como um timestamp ISO 8601 em UTC
title, textO título e a frase de resumo que o Slack e o Teams exibem
urlO relatório no AutoPSEO, ou null para testes
payload.fieldsOs valores rotulados que o Slack exibe como campos e o Teams como fatos
payload.tablecolumns e rows para relatórios e resumos; caso contrário, null
sourceSempre autopseo

As razões são frações: um change de -0.25 é uma queda de 25%, e um ctr de 0.034 é 3,4%.

Tipos de evento

event_typeEnviado quandoChaves extras em payload
traffic_drop, traffic_spike, position_drop, ctr_drop, new_lost_rankings, anomaly, index_flip, rank_drop, audit_regressionUma regra de alerta dispara, no agendamento ou por meio de Test ruledetector, window, range (as datas, ou null para index_flip, rank_drop e audit_regression), result
scheduled_reportUm relatório agendado é enviado, no agendamento ou por meio de Send nowreportType (summary, queries, pages ou rankings), range (datas mais um label), totals, previous
report_summaryAlguém usa Send to Slack na página de um relatórioNenhuma: os números estão em fields e table
testAlguém clica em Send test no webhooksample, sempre true

result repete o que o detector mediu: fired, metric, value, baseline, change (null quando não há com o que comparar), severity e summary, além de z, o z-score modificado, no caso de anomaly. totals e previous contêm clicks, impressions, ctr e position das duas janelas de um relatório. O que cada detector mede está descrito em Alertas.

Como verificar a assinatura

A assinatura é um HMAC-SHA256 dos bytes exatos enviados pelo AutoPSEO, calculado com o signing secret do webhook como chave e escrito como sha256= mais hexadecimal em minúsculas. Para verificá-la:

  1. Leia o corpo bruto da requisição antes de qualquer parsing de JSON. Fazer o parsing e serializar de novo pode alterar os bytes.
  2. Calcule o HMAC-SHA256 desses bytes, usando o secret como texto: a string de 64 caracteres exatamente como é exibida, sem decodificá-la de hexadecimal.
  3. Adicione o prefixo sha256= e compare o resultado com o cabeçalho X-AutoPSEO-Signature em tempo constante.
  4. Rejeite a requisição se forem diferentes. Caso contrário, responda imediatamente com um status 2xx e faça o trabalho mais demorado depois.

Um receptor para Node.js sem dependências:

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

A verificação de tamanho vem primeiro porque o timingSafeEqual do Node lança uma exceção quando os dois buffers têm tamanhos diferentes.

Regras de entrega

  • Cada mensagem recebe uma única tentativa, com timeout de 10 segundos. Qualquer resposta diferente de 2xx conta como falha e fica registrada no Delivery history com o código de status e o início do corpo da resposta.
  • Redirecionamentos não são seguidos. Uma resposta 3xx falha com uma observação para usar a URL final.
  • Nada é reenviado por temporizador. Um alerta com falha não é marcado como enviado, então a próxima verificação o avalia de novo e o publica se ele ainda disparar: na manhã seguinte para a maioria dos detectores, na hora seguinte para as mudanças de indexação. Um relatório agendado com falha não é reenviado no mesmo período; use Send now depois de corrigir o endpoint.
  • O id é criado a cada requisição, portanto identifica uma entrega, e não um evento. Para eliminar duplicatas de alertas, combine event_type, site_url e a data de occurred_at: uma regra publica no máximo uma vez por propriedade por dia UTC, a menos que alguém execute Test rule.

O signing secret

O AutoPSEO mostra o signing secret uma única vez, quando você salva o webhook, e a lista nunca o exibe novamente. Guarde-o de imediato na configuração do seu receptor, junto ao endpoint que ele protege.

A própria URL é armazenada criptografada, e a lista mostra apenas o host e os últimos caracteres. Excluir um webhook também exclui todas as regras que publicam nele. Para um cartão legível em um canal do Teams, em vez de JSON, use o Microsoft Teams.

Coloque o seu conteúdo de SEO no piloto automático

Conecte o Search Console e o seu site. O AutoPSEO analisa tudo e planeja os primeiros temas na hora. Sem cartão de crédito.