@happyvertical/smrt-webhooks
Outbound webhook subscriptions with HMAC-signed delivery to public HTTPS endpoints, a durable jobs queue, retries, and a safe delivery log.
What it gives you
Outbound webhook subscriptions with HMAC-signed delivery to public HTTPS endpoints, a durable jobs queue, retries, and a safe delivery log.
- 01WebhookChangeFeed reads the committed change feed, including delete tombstones, and advances a persisted cursor only after enqueue is durable
- 02A unique (tenant, subscription, event) outbox row and its job enqueue commit in one transaction; repeated dispatch is a no-op
- 03Only HTTPS port 443 to public unicast addresses, DNS pinned, no redirects, bounded deadlines
Two publication paths, never both
The durable path polls the change feed per tenant context and publishes identity-only payloads. registerWebhookModelEvents is a low-latency hook binding with an explicit model allowlist, but a crash between source commit and enqueue can miss an event. Do not enable both for the same models. A pruned cursor raises WebhookHistoryExpiredError and stops rather than dropping history.
At-least-once delivery
Five attempts use the jobs package’s exponential retry. A delivery lease prevents overlapping attempts; an expired lease permits recovery after worker death. Receivers must deduplicate the x-smrt-delivery header. The signature is sha256 HMAC over the timestamp and the exact persisted body.
Administration stays on the server
WebhookAdminService authorizes administrators through a host callback. The WebhookAdmin component takes subscriptions, deliveries, and onCreate, onToggle, onReplay callbacks; it never receives signing secrets. The integrations.webhooks recipe declares a server runtime and a settings panel, not model navigation.
Package UI
Components in this package
Import these public components directly. When the package also exports playground entries, the next tab renders its real components with package-owned example data.
Package previews
No playground module yet
This package does not currently export a ./playground module. Its component names and import path remain available in the Components tab.
Intentionally not registered
Generated interface
REST
The exact route set comes from each model's @smrt({ api }) policy
and the application manifest—not from a second controller definition.
Secrets and payloads are sensitive fields, so generated REST, MCP, WebMCP, and CLI access is disabled. The host exposes administration through its own authenticated routes.
Generated interface
MCP
AI tools are generated from the methods you explicitly include. Their inputs are validated against the same model metadata used by REST and CLI.
Secrets and payloads are sensitive fields, so generated REST, MCP, WebMCP, and CLI access is disabled. The host exposes administration through its own authenticated routes.
Browser-native agent interface
WebMCP
The generated web definitions carry the same tool names, descriptions, and JSON Schema
inputs as MCP. smrt-web registers them with document.modelContext.
Secrets and payloads are sensitive fields, so generated REST, MCP, WebMCP, and CLI access is disabled. The host exposes administration through its own authenticated routes.
Generated interface
CLI
The app CLI turns manifest resources into predictable operator commands while keeping package-specific actions close to their models.
Secrets and payloads are sensitive fields, so generated REST, MCP, WebMCP, and CLI access is disabled. The host exposes administration through its own authenticated routes.