ObjectStackObjectStack

Webhook

Webhook protocol schemas

Webhook Trigger Event When should this webhook fire?

These mirror the record events the engine actually emits (data.record.created / updated / deleted), which the webhook auto-enqueuer maps to create / update / delete. Only events with a real producer are declared here — an author can't subscribe to something that never fires.

Bulk triggers (#4639). bulk_update / bulk_delete map to the engine's aggregate data.records.updated / data.records.deleted, emitted when a predicate write (multi: trueIDataDriver.updateMany/deleteMany) affects a set of rows the driver reports only as a count. They are separate trigger values, not extra sources for update / delete, because their delivery has a different SHAPE: no recordId, no record body, just object + matched. Folding them into the per-record triggers would send every existing subscriber a body missing the fields it reads — the same class of breakage as the pre-#4626 recordId: '' fabrication, arriving from the other direction. A webhook that wants both subscribes to both.

Deliberately NOT triggers (#3196):

  • undelete — there is no soft-delete / restore capability in the engine (delete is a hard delete; no deleted_at convention, no restore operation, no data.record.undeleted emit), so it had no event source. Reintroduce it only alongside a real restore subsystem that emits an undelete event.
  • api (manual/programmatic fire) — no manual fire path exists (the only webhook HTTP surface re-queues already-failed deliveries). Reintroduce it with a real "fire this webhook now" endpoint/service, not as a bare enum value that silently never fires.

Source: packages/spec/src/automation/webhook.zod.ts

TypeScript Usage

import { WebhookSchema, WebhookTriggerType } from '@objectstack/spec/automation';
import type { Webhook, WebhookTriggerType } from '@objectstack/spec/automation';

// Validate data
const result = WebhookSchema.parse(data);

Webhook

Properties

PropertyTypeRequiredDescription
namestringWebhook unique name (lowercase snake_case)
labelstringoptionalHuman-readable webhook label
objectstringoptionalObject whose record events (create/update/delete, bulk_update/bulk_delete) trigger this webhook
triggersEnum<'create' | 'update' | 'delete' | 'bulk_update' | 'bulk_delete'>[]optionalEvents that trigger execution
urlstringExternal webhook endpoint URL
methodEnum<'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE'>HTTP method
headersRecord<string, string>optionalCustom HTTP headers
timeoutMsintegerRequest timeout in milliseconds
secretstringoptionalSigning secret for HMAC signature verification
isActivebooleanWhether webhook is active
descriptionstringoptionalWebhook description
protection{ lock: Enum<'none' | 'no-overlay' | 'no-delete' | 'full'>; reason: string; docsUrl?: string }optionalPackage author protection block — lock policy for this webhook.
_lockEnum<'none' | 'no-overlay' | 'no-delete' | 'full'>optionalItem-level lock — controls overlay & delete (ADR-0010).
_lockReasonstringoptionalHuman-readable reason shown when a write is refused by _lock.
_lockSourceEnum<'artifact' | 'package' | 'env-forced'>optionalLayer that set _lock (artifact | package | env-forced).
_provenanceEnum<'package' | 'org' | 'env-forced'>optionalOrigin of the item (package | org | env-forced).
_packageIdstringoptionalOwning package machine id.
_packageVersionstringoptionalOwning package version.
_lockDocsUrlstringoptionalOptional documentation link surfaced next to _lockReason.

WebhookTriggerType

Allowed Values

  • create
  • update
  • delete
  • bulk_update
  • bulk_delete

On this page