Webhooks
Subscribe to organization events and handle signed deliveries securely.
Outcome: Register organization-scoped webhook subscriptions and consume versioned, signed event deliveries.
Event registry
Webhook subscriptions use the canonical event registry shared with notification-facing metadata. Event identifiers are stable dotted strings such as lead.created. The registry is deduplicated and sorted before it is returned by the webhook event-listing endpoint.
Each delivery uses an envelope with:
{
"id": "webhook_123",
"event": "lead.created",
"version": 1,
"data": {}
}The webhook owner is the organization that created the subscription. Create, list, read, update, and delete operations must remain organization-scoped and require the existing authenticated organization procedure.
Signing and retries
Deliveries are sent only to https:// targets that pass the server-side URL policy. Plain HTTP, credentials in the URL, localhost, link-local, loopback, and RFC1918 IPv4 targets are rejected. DNS resolution and deployment egress controls are still required because URL validation alone cannot prevent every DNS-rebinding or network-policy risk.
The request includes:
X-Webhook-Signature: t=<unix-seconds>,v1=<sha256-hmac>X-Webhook-Idempotency-Key: <sha256 key>X-Event-Name: <event identifier>Content-Type: application/json
The HMAC input is <timestamp>.<raw request body>, using the subscription secret as the key. The idempotency key is stable for the webhook, event identifier, and exact body, so receivers can collapse queue retries. The existing queue boundary owns retry behavior: non-success responses and delivery errors remain failures for queue retry handling.
Secrets are write-only in public webhook API responses. Logs include delivery context but not secrets or signature key material.
Current limitations
- External delivery remains disabled in tests; tests use pure helpers and synthetic data only.
- The current registry contains event metadata discovered from registered Igniter procedures; product owners still need to approve the public event catalog and versioning policy.
- Private-network protection is a literal URL preflight, not a replacement for network-level egress allowlists and DNS-aware IP enforcement.
Incoming webhooks
For incoming providers, verify the provider-specific signature against the raw request body before parsing and process repeated deliveries idempotently.
See also
- ../../api/overview
- ../../deployment/setup-stripe