Dokumentation
Utgående webhooks: payload och signatur
Ta emot AutoPSEO-aviseringar och rapporter som signerad JSON på valfri HTTPS-endpoint: förfrågningshuvuden, fält i bodyn, händelsetyper och hur du verifierar signaturen.
En utgående webhook skickar AutoPSEO:s aviseringar, schemalagda rapporter, testmeddelanden och rapportsammanfattningar till en endpoint som du driver själv, som en JSON-POST per meddelande signerad med HMAC-SHA256. Använd den för att mata Zapier, Make, n8n, ett incidentverktyg eller din egen kod; inget konto i Slack eller Teams behövs. Letar du efter webhooken som levererar artiklar till din webbplats? Den hör till innehållsmotorn: se innehållsleverans.
Lägg till en webhook
- Klicka på New webhook i avsnittet Outbound webhooks.
- Ge den ett Name och klistra in endpointens URL. Den måste vara publik HTTPS: vanlig
http,localhost, namn som slutar på.localeller.internal, värdnamn utan punkt samt privata eller länklokala IP-adresser avvisas. - Kopiera den signing secret som visas när du har sparat. Den visas bara en enda gång.
- Klicka på Send test för att skicka en
test-händelse och koppla sedan schemalagda rapporter eller aviseringar till webhooken.
Så ser en webhook-förfrågan ut
Varje meddelande är en POST med dessa huvuden:
| Huvud | Värde |
|---|---|
Content-Type | application/json |
User-Agent | AutoPSEO-Webhook/1.0 |
X-AutoPSEO-Event | Händelsetypen, till exempel traffic_drop |
X-AutoPSEO-Signature | sha256= följt av 64 hexadecimala tecken i gemener |
Här är en avisering om trafikfall för en domänegendom från körningen 06:00 UTC den 12 oktober 2026, formaterad för läsning (i själva förfrågan är det kompakt JSON, och värdena för id och site_id är påhittade):
{
"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"
}
Fälten på toppnivå är desamma för alla händelser:
| Fält | Innehåll |
|---|---|
id | En slumpmässig hexsträng på 32 tecken, ny för varje förfrågan |
event_type | Vad som hände (se nästa avsnitt) |
severity | critical, high, medium eller low för aviseringar; info för rapporter, sammanfattningar och tester |
site_id | AutoPSEO:s id för egendomen, eller null för tester och demoegendomen |
site_url | Search Console-egendomen, till exempel sc-domain:example.com eller https://www.example.com/, eller null för tester |
occurred_at | När meddelandet byggdes, som en ISO 8601-tidsstämpel i UTC |
title, text | Rubriken och sammanfattningsmeningen som Slack och Teams visar |
url | Rapporten i AutoPSEO, eller null för tester |
payload.fields | De namngivna värden som Slack visar som fält och Teams som fakta |
payload.table | columns och rows för rapporter och sammanfattningar, annars null |
source | Alltid autopseo |
Kvoter anges som bråktal: en change på -0.25 är en minskning med 25 %, och en ctr på 0.034 är 3,4 %.
Händelsetyper
event_type | Skickas när | Extra nycklar i payload |
|---|---|---|
traffic_drop, traffic_spike, position_drop, ctr_drop, new_lost_rankings, anomaly, index_flip, rank_drop, audit_regression | En aviseringsregel utlöses, enligt schema eller via Test rule | detector, window, range (datumen, eller null för index_flip, rank_drop och audit_regression), result |
scheduled_report | En schemalagd rapport skickas, enligt schema eller via Send now | reportType (summary, queries, pages eller rankings), range (datum plus en label), totals, previous |
report_summary | Någon använder Send to Slack på en rapportsida | Inga: siffrorna finns i fields och table |
test | Någon klickar på Send test på webhooken | sample, alltid true |
result upprepar vad detektorn mätte: fired, metric, value, baseline, change (null när det inte finns något att jämföra med), severity och summary, samt z, det modifierade z-värdet, för anomaly. totals och previous innehåller clicks, impressions, ctr och position för rapportens två perioder. Vad varje detektor mäter beskrivs under Aviseringar.
Så verifierar du signaturen
Signaturen är en HMAC-SHA256 av exakt de bytes som AutoPSEO skickade, nycklad med webhookens signing secret och skriven som sha256= plus hex i gemener. Så här kontrollerar du den:
- Läs den råa förfrågningsbodyn innan någon JSON-tolkning sker. Om du tolkar och serialiserar om den kan bytesen ändras.
- Beräkna HMAC-SHA256 över dessa bytes med hemligheten som text: strängen på 64 tecken precis som den visas, inte avkodad från hex.
- Lägg till prefixet
sha256=och jämför resultatet med huvudetX-AutoPSEO-Signaturei konstant tid. - Avvisa förfrågan om de skiljer sig åt. Svara annars direkt med en 2xx-status och gör det tidskrävande arbetet efteråt.
En mottagare för Node.js utan beroenden:
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);
Längdkontrollen kommer först eftersom Nodes timingSafeEqual kastar ett fel när de två buffertarna har olika längd.
Leveransregler
- Varje meddelande får ett försök med en timeout på 10 sekunder. Alla svar utom 2xx räknas som ett misslyckande och sparas i Delivery history med statuskoden och början av din svarsbody.
- Omdirigeringar följs inte. Ett 3xx-svar misslyckas med en uppmaning att använda den slutliga URL:en.
- Inget skickas om automatiskt på timer. En misslyckad avisering markeras inte som skickad, så nästa kontroll utvärderar den igen och postar om den fortfarande utlöses: nästa morgon för de flesta detektorer, nästa timme för indexförändringar. En misslyckad schemalagd rapport skickas inte om under samma period, så använd Send now när du har lagat endpointen.
idskapas per förfrågan, så det identifierar en leverans och inte en händelse. För att avduplicera aviseringar kan du kombineraevent_type,site_urloch datumet ioccurred_at: en regel postar högst en gång per egendom och UTC-dygn, om inte någon kör Test rule.
Signing secret
AutoPSEO visar signing secret en enda gång, när du sparar webhooken, och listan visar den aldrig igen. Spara den direkt i mottagarens konfiguration, tillsammans med den endpoint som den skyddar.
Själva URL:en lagras krypterad, och listan visar bara dess värdnamn och sista tecken. När du tar bort en webhook tas även alla regler som postar till den bort. Vill du ha ett lättläst kort i en Teams-kanal i stället för JSON, använd Microsoft Teams.