Документація
Вихідні вебхуки: тіло запиту та підпис
Отримуйте сповіщення й звіти AutoPSEO у вигляді підписаного JSON на будь-якій HTTPS-кінцевій точці: заголовки запиту, поля тіла, типи подій і перевірка підпису.
Вихідний вебхук надсилає сповіщення AutoPSEO, заплановані звіти, тестові повідомлення та підсумки звітів на кінцеву точку, яку ви підтримуєте, у вигляді одного JSON-запиту POST на кожне повідомлення, підписаного за допомогою HMAC-SHA256. Використовуйте його для Zapier, Make, n8n, інструмента керування інцидентами чи власного коду; обліковий запис Slack або Teams не потрібен. Шукаєте вебхук, який доставляє статті на ваш сайт? Він належить до контент-рушія: див. доставка контенту.
Додавання вебхука
- У розділі Outbound webhooks натисніть New webhook.
- Вкажіть Name і вставте URL кінцевої точки. Це має бути публічний HTTPS: звичайний
http,localhost, імена із закінченням.localабо.internal, хости без крапки, а також приватні й link-local IP-адреси відхиляються. - Скопіюйте signing secret, який з'явиться після збереження. Його показано лише один раз.
- Натисніть Send test, щоб надіслати подію
test, а потім прив'яжіть до вебхука заплановані звіти або сповіщення.
Як виглядає запит вебхука
Кожне повідомлення — це POST із такими заголовками:
| Заголовок | Значення |
|---|---|
Content-Type | application/json |
User-Agent | AutoPSEO-Webhook/1.0 |
X-AutoPSEO-Event | Тип події, наприклад traffic_drop |
X-AutoPSEO-Signature | sha256=, за яким іде 64 символи шістнадцяткового запису в нижньому регістрі |
Ось сповіщення про падіння трафіку для доменної властивості за запуском о 06:00 UTC 12 жовтня 2026 року, у зручному для читання форматі (насправді передається компактний JSON, а значення id і site_id вигадані):
{
"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"
}
Поля верхнього рівня однакові для всіх подій:
| Поле | Що містить |
|---|---|
id | Випадковий 32-символьний шістнадцятковий рядок, новий для кожного запиту |
event_type | Що сталося (див. наступний розділ) |
severity | critical, high, medium або low для сповіщень; info для звітів, підсумків і тестів |
site_id | Ідентифікатор властивості в AutoPSEO або null для тестів і демонстраційної властивості |
site_url | Властивість Search Console, наприклад sc-domain:example.com або https://www.example.com/, чи null для тестів |
occurred_at | Момент формування повідомлення у форматі ISO 8601 за UTC |
title, text | Заголовок і підсумкове речення, які показують Slack і Teams |
url | Звіт в AutoPSEO або null для тестів |
payload.fields | Підписані значення, які Slack показує як поля, а Teams — як факти |
payload.table | columns і rows для звітів і підсумків, в інших випадках null |
source | Завжди autopseo |
Співвідношення подаються як частки: change зі значенням -0.25 означає спад на 25%, а ctr зі значенням 0.034 — 3,4%.
Типи подій
event_type | Коли надсилається | Додаткові ключі в payload |
|---|---|---|
traffic_drop, traffic_spike, position_drop, ctr_drop, new_lost_rankings, anomaly, index_flip, rank_drop, audit_regression | Спрацьовує правило сповіщення за розкладом або через Test rule | detector, window, range (дати, або null для index_flip, rank_drop і audit_regression), result |
scheduled_report | Надсилається запланований звіт за розкладом або через Send now | reportType (summary, queries, pages або rankings), range (дати та label), totals, previous |
report_summary | Хтось використовує Send to Slack на сторінці звіту | Немає: показники містяться в fields і table |
test | Хтось натискає Send test для вебхука | sample, завжди true |
result повторює те, що виміряв детектор: fired, metric, value, baseline, change (null, якщо немає з чим порівнювати), severity і summary, а для anomaly — ще й z, модифікований z-показник. totals і previous містять clicks, impressions, ctr і position для двох періодів звіту. Що саме вимірює кожен детектор, описано в розділі Сповіщення.
Як перевірити підпис
Підпис — це HMAC-SHA256 від точних байтів, які надіслав AutoPSEO, із ключем у вигляді signing secret вебхука, записаний як sha256= плюс шістнадцятковий запис у нижньому регістрі. Щоб його перевірити:
- Прочитайте необроблене тіло запиту до будь-якого розбору JSON. Розбір і повторна серіалізація можуть змінити байти.
- Обчисліть HMAC-SHA256 від цих байтів, використовуючи секрет як текст: 64-символьний рядок точно так, як його показано, без декодування з шістнадцяткового запису.
- Додайте префікс
sha256=і порівняйте результат із заголовкомX-AutoPSEO-Signatureза сталий час. - Відхиліть запит, якщо значення відрізняються. Інакше одразу відповідайте статусом 2xx, а повільну роботу виконуйте потім.
Приймач для Node.js без залежностей:
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);
Перевірка довжини йде першою, оскільки timingSafeEqual у Node викидає виняток, коли довжини двох буферів різні.
Правила доставки
- Кожне повідомлення отримує одну спробу з тайм-аутом 10 секунд. Будь-яка відповідь, крім 2xx, вважається невдалою й зберігається в Delivery history разом із кодом статусу та початком тіла вашої відповіді.
- Перенаправлення не виконуються. Відповідь 3xx завершується помилкою з підказкою використати кінцевий URL.
- Автоматичних повторних спроб за таймером немає. Невдале сповіщення не позначається як надіслане, тож наступна перевірка оцінить його знову й надішле, якщо воно все ще спрацьовує: наступного ранку для більшості детекторів і наступної години для
index_flip. Невдалий запланований звіт не надсилається повторно в тому самому періоді, тому після виправлення кінцевої точки скористайтеся Send now. idстворюється для кожного запиту, тому він ідентифікує доставку, а не подію. Щоб прибирати дублікати сповіщень, поєднуйтеevent_type,site_urlі дату зoccurred_at: правило надсилає не більше одного повідомлення на властивість за добу UTC, якщо тільки хтось не запускає Test rule.
Signing secret
AutoPSEO показує signing secret один раз, під час збереження вебхука, а список більше ніколи його не показує. Одразу збережіть його в конфігурації вашого приймача поруч із кінцевою точкою, яку він захищає.
Сам URL зберігається в зашифрованому вигляді, а список показує лише його хост і останні символи. Видалення вебхука також видаляє всі правила, що надсилають повідомлення на нього. Якщо вам потрібна зручна для читання картка в каналі Teams, а не JSON, скористайтеся Microsoft Teams.