Webhooks

Configure filtered organization webhook subscriptions and follow delivery progress.

Documentation owner:
BlendDuck Documentation
Last reviewed:

Create a subscription

An owner or admin can register a public HTTPS destination, subscribe to explicit versioned events, disable it, rotate its signing secret, and delete it through the stable /api/v1 API.

GET, POST              /api/v1/webhooks
GET, PATCH, DELETE     /api/v1/webhooks/:endpointId
POST                   /api/v1/webhooks/:endpointId/rotate
POST                   /api/v1/webhooks/:endpointId/test
GET                    /api/v1/webhooks/:endpointId/deliveries
GET                    /api/v1/webhooks/:endpointId/deliveries/:deliveryId
POST                   /api/v1/webhooks/:endpointId/deliveries/:deliveryId/replay

Use webhooks:read for list/detail access and webhooks:write for lifecycle operations. Creation and rotation return a random signing secret in a non-cacheable response. It is shown only once; later reads expose masked metadata while the database stores encrypted material.

Available filters are channel.connected.v1, channel.disconnected.v1, channel.reconnect-required.v1, media.created.v1, post.created.v1, post.updated.v1, post.deleted.v1, post.scheduled.v1, post.published.v1, post.failed.v1, and webhook.test.v1. Unknown or duplicate filters fail validation.

Destinations must be public HTTPS URLs without credentials, query strings, fragments, custom ports, or literal local/private addresses.

Verify signed delivery

Every POST carries a stable Webhook-Id, Unix Webhook-Timestamp, and Webhook-Signature. Verify the v1= HMAC-SHA256 over <id>.<timestamp>.<exact raw body> before parsing, compare in constant time, and reject timestamps outside five minutes.

Receivers must deduplicate the stable event ID because delivery is at least once. Retryable HTTP/network failures use bounded exponential backoff, each request has a 10-second default timeout, redirects are rejected, and DNS is checked for non-public answers immediately before sending. Event, delivery, and attempt evidence expires after 72 hours.

Test, inspect, and replay

The dashboard Settings page uses persisted APIs to show endpoint health, retained public event payloads, response status and latency, and complete attempt history. Owners and admins can send an idempotent webhook.test.v1 event, disable or re-enable an endpoint, and queue one additional attempt for an unexpired exhausted delivery. Replay retains the original stable event ID and rejects succeeded, pending, processing, expired, disabled, concurrent, and cross-organization requests.

Signing material, worker leases, response bodies, and internal fields are not part of log responses. Test and replay require webhooks:write; reads require webhooks:read; mutations carry person and credential attribution into the redacted audit ledger.

Use the OpenAPI schema for the exact request fields, event enumerations, response bodies, and required scopes.