Разделы документации
ОбзорБыстрый стартРедакции и возможностиМодели и поляРедактор контентаМедиатекаЛокализацияПубликация и работа командыAPI, SDK и генерация типовРасширения и инструментыРабочие проектыЗадания, вебхуки и наблюдаемостьАудит и управление даннымиСоветники и доверие к плагинамКорпоративный входПространства, квоты и масштабированиеCommerce и PortalПрава и безопасностьРазвёртывание и обновленияЛицензии и установка пакетовТекущие ограниченияПомощь и диагностикаДанные в кабинетеCore CMSDeveloper PlatformProduction UseWorkflowOperationsComplianceAI AssistantsPlugin TrustEnterprise IdentityEnterprise ScaleEnterprise DeploymentCommerce BundlePortal BundleNotty CMS DocumentationAuth & SecurityContent ModelingDeploymentEcosystem & Packaging ConventionsEditions and First-party ModulesExtensibilityGetting StartedMedia ManagementModule Extraction PathDraft & PublishUpgrade GuideWebhooks & IntegrationsCookbook: Blog with Next.jsCookbook: Custom PluginCookbook: Multilingual SiteOperations DocsBackup AutomationDeployment BlueprintsRunbook — Восстановление БД из бэкапаRunbook — Плановый деплойRunbook — Реакция на инцидентRunbook — Откат релизаRunbook — Горизонтальное масштабированиеRunbook — Ротация секретовRunbook — Major upgradeSecrets ManagementNotty CMS — Capability MapNotty Configuration ModelGenerated App ContractComponents and Dynamic ZonesMiddleware SystemPerformance & Scaling ToolkitDisaster Recovery PlaybookDistribution Model
Документация / Технический справочник

Webhooks & Integrations

Техническое руководство из исходного проекта Notty. Примеры, параметры и эксплуатационные ограничения.

Все редакцииОбновлено 2026-09-30

Notty CMS fires webhooks on content events, letting you connect external services, trigger builds, or sync data.

Create a Webhook

curl -X POST http://localhost:2102/api/webhooks \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Deploy on Publish",
    "url": "https://api.vercel.com/v1/integrations/deploy/prj_...",
    "events": ["entry.publish"],
    "enabled": true
  }'

Webhook Events

Event Trigger
entry.create New content entry created
entry.update Content entry updated
entry.delete Content entry deleted
entry.publish Content entry published
entry.unpublish Content entry unpublished
entry.preview.invalidate Preview cache should be cleared

Filter by Content Type

Only fire the webhook for specific content types:

{
  "name": "Article Events",
  "url": "https://hooks.example.com/notty",
  "events": ["entry.create", "entry.update", "entry.publish"],
  "content_types": ["article", "page"],
  "enabled": true
}

Webhook Signing

Add a secret to verify that webhook payloads come from your Notty instance:

{
  "name": "Signed Webhook",
  "url": "https://hooks.example.com/notty",
  "events": ["entry.publish"],
  "secret": "whsec_my-signing-secret"
}

Notty signs each payload with HMAC-SHA256. Verify the signature in your handler:

// Node.js webhook handler example
import crypto from 'crypto';

function verifyWebhook(payload, signature, secret) {
  const expected = crypto.createHmac('sha256', secret).update(payload).digest('hex');
  return crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected));
}

// Express handler
app.post('/webhook', (req, res) => {
  const signature = req.headers['x-webhook-signature'];
  const isValid = verifyWebhook(JSON.stringify(req.body), signature, 'whsec_my-signing-secret');

  if (!isValid) {
    return res.status(401).send('Invalid signature');
  }

  const { event, data } = req.body;
  console.log(`Received ${event}:`, data);
  res.status(200).send('OK');
});

Custom Headers

Add custom headers to webhook requests:

{
  "name": "With Auth Header",
  "url": "https://hooks.example.com/notty",
  "events": ["entry.publish"],
  "headers": {
    "X-API-Key": "your-external-api-key",
    "X-Source": "notty-cms"
  }
}

Webhook Management

Method Path Description
GET /api/webhooks List all webhooks
POST /api/webhooks Create webhook
GET /api/webhooks/:id Get webhook details
PUT /api/webhooks/:id Update webhook
DELETE /api/webhooks/:id Delete webhook
POST /api/webhooks/:id/test Send a test payload
GET /api/webhooks/:id/logs View delivery logs
POST /api/webhooks/:id/replay/:logId Replay a failed delivery
GET /api/webhooks/:id/stats Delivery statistics

Delivery Logs

Every webhook delivery is logged. View delivery history:

curl http://localhost:2102/api/webhooks/1/logs \
  -H "Authorization: Bearer $TOKEN"

Each log entry includes: status code, response time, request/response headers, and payload.

Failed Deliveries & Retry

Notty retries failed deliveries automatically. View the dead letter queue:

curl http://localhost:2102/api/webhooks/dead-letter \
  -H "Authorization: Bearer $TOKEN"

Replay a specific failed delivery:

curl -X POST http://localhost:2102/api/webhooks/1/replay/42 \
  -H "Authorization: Bearer $TOKEN"

Test a Webhook

Send a test payload without triggering real events:

curl -X POST http://localhost:2102/api/webhooks/1/test \
  -H "Authorization: Bearer $TOKEN"

Use Cases

Trigger Static Site Rebuild

Fire a webhook on entry.publish to trigger a Vercel/Netlify deploy:

{
  "name": "Vercel Deploy",
  "url": "https://api.vercel.com/v1/integrations/deploy/prj_...",
  "events": ["entry.publish", "entry.unpublish"],
  "enabled": true
}

Sync to Search Engine

Push content updates to Algolia or Meilisearch:

{
  "name": "Algolia Sync",
  "url": "https://your-api.com/webhooks/algolia-sync",
  "events": ["entry.create", "entry.update", "entry.delete", "entry.publish"],
  "content_types": ["article", "product"],
  "secret": "whsec_algolia-sync-secret"
}

Notify a Slack Channel

Send notifications when content is published:

{
  "name": "Slack Notification",
  "url": "https://hooks.slack.com/services/T.../B.../...",
  "events": ["entry.publish"],
  "headers": { "Content-Type": "application/json" }
}

OpenAPI Documentation

Notty auto-generates an OpenAPI specification for your content API. Access the interactive docs at:

http://localhost:2102/api/_docs

The spec is generated from your content schemas, so it always reflects the current data model. The viewer uses Scalar UI and requires authenticated access.

Search across all content types:

curl "http://localhost:2102/api/search?q=typescript&limit=20" \
  -H "Authorization: Bearer $TOKEN"

Or search within a specific content type with searchFields:

curl "http://localhost:2102/api/content/article?search=typescript&searchFields=title,body" \
  -H "Authorization: Bearer $TOKEN"

Aggregation API

Run aggregate queries for dashboards and analytics:

# Count articles by category
curl "http://localhost:2102/api/content/article/aggregate?function=count&field=id&groupBy[]=category_id" \
  -H "Authorization: Bearer $TOKEN"

# Average product price
curl "http://localhost:2102/api/content/product/aggregate?function=avg&field=price" \
  -H "Authorization: Bearer $TOKEN"

Available functions: count, sum, avg, min, max.

GraphQL API

Notty also provides a GraphQL endpoint auto-generated from your content schemas:

curl -X POST http://localhost:2102/api/graphql \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "{ articles { data { id title body category { name } } } }"
  }'

Interactive GraphiQL playground is available at http://localhost:2102/api/graphql in the browser.

Источник: docs/guide/webhooks.md. Снимок документации исходного проекта. Технический справочник сохраняет язык оригинала.