Перейти к содержанию

Вебхуки

Регистрируйте исходящие HTTP-вебхуки, которые срабатывают при событиях записи в API (изменения страниц, медиафайлов и пользователей, обновления конфигурации, установки через GPM, обновления Grav). У каждого вебхука есть URL, список фильтров событий, необязательные собственные заголовки, сгенерированный секрет для подписи HMAC и журнал доставок.

Разрешения: api.webhooks.read / api.webhooks.write. Секреты генерируются сервером и всегда маскируются в ответах API, кроме одного раза — в ответе, создающем вебхук.

Допустимые имена событий

* (все), page.created, page.updated, page.deleted, page.moved, page.translated, pages.reordered, media.uploaded, media.deleted, user.created, user.updated, user.deleted, config.updated, gpm.installed, gpm.removed, grav.upgraded.

Доставки

Каждая доставка — это JSON POST вида {"event": "...", "timestamp": "<ISO 8601>", "data": {...}, "webhook_id": "wh_..."}. Grav добавляет к каждой доставке следующие заголовки:

Заголовок Значение
X-Grav-Signature Hex HMAC-SHA256 необработанного тела запроса с ключом-секретом вебхука
X-Grav-Event Имя события вебхука, например page.updated
X-Grav-Delivery Уникальный идентификатор доставки (dlv_...)

Собственные headers вебхука могут задавать другие заголовки, включая Content-Type и User-Agent, но не могут заменить эти три: создание или обновление вебхука с одним из них возвращает 422. Принимаются только URL http и https, а URL, который разрешается в приватный, loopback-, link-local или зарезервированный адрес, отклоняется — как при сохранении, так и повторно во время доставки. Перенаправления не выполняются.

Вебхук, у которого 5 доставок подряд завершились неудачей, автоматически отключается с указанием disabled_reason; успешная доставка сбрасывает счётчик. Хранятся последние 50 доставок каждого вебхука.

Список вебхуков

GET /webhooks

Выводит все настроенные вебхуки. Секреты маскируются (первые 6 и последние 4 символа сохраняются, середина скрыта).

Ответ

{"data": [{"id": "wh_abc123", "url": "https://example.com/hooks/grav", "secret": "whsec_************************************************a1b2", "events": ["page.created", "page.updated"], "enabled": true, "headers": {}, "created": 1774008000, "failure_count": 0}]}

Коды ответов

Код Описание
200 Вебхуки возвращены.
401 Не авторизован.
403 Нет разрешения api.webhooks.read.

Создание вебхука

POST /webhooks

Регистрирует новый вебхук. URL должен быть абсолютным URL http или https, который не разрешается в приватный или зарезервированный адрес. События (если переданы) должны быть из разрешённого списка (см. вводную главу). Сервер генерирует идентификатор вебхука и секрет для подписи; ответ — единственный раз, когда возвращается полный секрет.

Параметры

Имя Тип Обязательный Описание
url string Да Абсолютный URL HTTP(S), на который отправляются POST-запросы с данными.
events array Нет Фильтр событий в виде JSON-массива имён событий. Используйте ["*"], чтобы получать все события, или перечислите конкретные события. По умолчанию ["*"]. Всё, кроме массива допустимых имён, даёт 422.
headers object Нет Собственные заголовки, отправляемые с каждой доставкой, в виде объекта «имя заголовка → значение». X-Grav-Signature, X-Grav-Event и X-Grav-Delivery (в любом регистре) отклоняются с 422, как и имена или значения, содержащие переводы строк.
enabled boolean Нет По умолчанию true.

Запрос

{"url": "https://example.com/hooks/grav", "events": ["page.created", "page.updated"], "enabled": true}

Ответ

{"data": {"id": "wh_abc123", "url": "https://example.com/hooks/grav", "secret": "whsec_0123456789abcdef0123456789abcdef0123456789abcdef", "events": ["page.created", "page.updated"], "enabled": true, "headers": {}, "created": 1774526400, "failure_count": 0}}

Коды ответов

Код Описание
201 Вебхук создан; заголовок Location указывает на новый вебхук.
401 Не авторизован.
403 Нет разрешения api.webhooks.write.
422 Отсутствует или неверен url (неверный синтаксис, не http/https либо приватный или зарезервированный адрес), events не является массивом допустимых имён событий, либо headers неверны или зарезервированы.

Получение вебхука

GET /webhooks/{id}

Возвращает один вебхук по id. Секрет маскируется. Ответ содержит заголовок ETag.

Параметры

Имя Тип Обязательный Описание
id string Да Идентификатор вебхука (параметр пути).

Ответ

{"data": {"id": "wh_abc123", "url": "https://example.com/hooks/grav", "secret": "whsec_************************************************a1b2", "events": ["page.created", "page.updated"], "enabled": true, "headers": {}, "created": 1774008000, "failure_count": 0}}

Коды ответов

Код Описание
200 Вебхук возвращён.
401 Не авторизован.
403 Нет разрешения api.webhooks.read.
404 Вебхук не найден.

Обновление вебхука

PATCH /webhooks/{id}

Частичное обновление: меняются только переданные поля. url, events и headers проверяются так же, как при создании. Секрет изменить нельзя. Повторное включение автоматически отключённого вебхука не сбрасывает его failure_count; это делает следующая успешная доставка.

Параметры

Имя Тип Обязательный Описание
id string Да Идентификатор вебхука (параметр пути).
url string Нет Новый URL.
events array Нет Заменяющий фильтр событий (JSON-массив имён событий).
headers object Нет Заменяющие собственные заголовки. Три заголовка X-Grav-*, которые задаёт Grav, отклоняются с 422.
enabled boolean Нет Включить или отключить вебхук, не удаляя его.

Запрос

{"url": "https://example.com/hooks/grav-v2", "events": ["page.created", "page.updated", "page.deleted"]}

Ответ

{"data": {"id": "wh_abc123", "url": "https://example.com/hooks/grav-v2", "secret": "whsec_************************************************a1b2", "events": ["page.created", "page.updated", "page.deleted"], "enabled": true, "headers": {}, "created": 1774008000, "failure_count": 0}}

Коды ответов

Код Описание
200 Вебхук обновлён.
401 Не авторизован.
403 Нет разрешения api.webhooks.write.
404 Вебхук не найден.
422 Неверный url, events не является массивом допустимых имён событий, либо headers неверны или зарезервированы.

Удаление вебхука

DELETE /webhooks/{id}

Удаляет вебхук. История доставок также удаляется.

Параметры

Имя Тип Обязательный Описание
id string Да Идентификатор вебхука (параметр пути).

Коды ответов

Код Описание
204 Вебхук удалён.
401 Не авторизован.
403 Нет разрешения api.webhooks.write.
404 Вебхук не найден.

Журнал доставок

GET /webhooks/{id}/deliveries

Журнал доставок одного вебхука с постраничной разбивкой, сначала новые. Каждая запись содержит идентификатор доставки, событие, URL, отправленные заголовки и тело запроса, статус ответа и первые 1000 символов тела ответа, длительность, флаг успеха, error для транспортных сбоев и метку времени Unix created. Хранятся только последние 50 доставок.

Параметры

Имя Тип Обязательный Описание
id string Да Идентификатор вебхука (параметр пути).
page integer Нет Номер страницы (по умолчанию 1).
per_page integer Нет Элементов на странице (по умолчанию plugins.api.pagination.default_per_page, 20).

Ответ

{"data": [{"id": "dlv_9f2c4e1a7b3d5f60", "event": "page.updated", "url": "https://example.com/hooks/grav", "request_headers": {"Content-Type": "application/json", "User-Agent": "Grav-Webhook/1.0", "X-Grav-Signature": "5d41402abc4b2a76b9719d911017c592...", "X-Grav-Event": "page.updated", "X-Grav-Delivery": "dlv_9f2c4e1a7b3d5f60"}, "request_body": {"event": "page.updated", "timestamp": "2026-09-21T12:00:00+00:00", "data": {"page": {"route": "/blog/hello", "title": "Hello", "slug": "hello"}}, "webhook_id": "wh_abc123"}, "created": 1790000000, "status_code": 200, "response_body": "ok", "duration_ms": 142, "success": true}], "meta": {"pagination": {"page": 1, "per_page": 20, "total": 1, "total_pages": 1}}, "links": {"self": "/api/v1/webhooks/wh_abc123/deliveries?page=1&per_page=20"}}

Коды ответов

Код Описание
200 Доставки возвращены.
401 Не авторизован.
403 Нет разрешения api.webhooks.read.
404 Вебхук не найден.

Тестовая доставка вебхука

POST /webhooks/{id}/test

Отправляет тестовую доставку (событие test с data.message, равным This is a test webhook delivery.) на URL вебхука и сразу возвращает запись доставки. Она подписывается и журналируется как настоящая доставка, а неудачный тест учитывается при автоматическом отключении после 5 сбоев как одна доставка. Используйте его, чтобы проверить, что эндпоинт доступен и проверяет подпись, не дожидаясь реального события. Возвращает 502 с той же записью доставки в теле, если получатель отвечает статусом вне 2xx или недоступен.

Параметры

Имя Тип Обязательный Описание
id string Да Идентификатор вебхука (параметр пути).

Ответ

{"data": {"id": "dlv_1a2b3c4d5e6f7a8b", "event": "test", "url": "https://example.com/hooks/grav", "request_headers": {"Content-Type": "application/json", "User-Agent": "Grav-Webhook/1.0", "X-Grav-Signature": "5d41402abc4b2a76b9719d911017c592...", "X-Grav-Event": "test", "X-Grav-Delivery": "dlv_1a2b3c4d5e6f7a8b"}, "request_body": {"event": "test", "timestamp": "2026-09-21T12:00:00+00:00", "data": {"message": "This is a test webhook delivery."}, "webhook_id": "wh_abc123"}, "created": 1790000000, "status_code": 200, "response_body": "ok", "duration_ms": 118, "success": true}}

Коды ответов

Код Описание
200 Тест доставлен успешно.
401 Не авторизован.
403 Нет разрешения api.webhooks.write.
404 Вебхук не найден.
502 Тестовая доставка не удалась; тело содержит запись доставки с success: false.