POSTs from ClutchCall to a URL you own.
You manage them on the Webhooks screen, which is wired to the unified
webhook plane (webhooks.*) with vertical: 'streams'. Each row in the table
is one webhook_endpoint: a URL, an event-type subscription, a signing secret,
and a health state.
This page explains what the event picker on that screen is actually storing and
how the dispatcher interprets it. Signing, retry/backoff behaviour, and refused
destinations are covered on the platform webhooks page.
Event types
The picker is catalog-driven. The console callswebhooks.catalog and reads
streams.groups from the returned registry; each entry is a group of concrete
event-type tokens:
The authoritative list of Streams event types is therefore whatever the registry
serves your org — the picker renders exactly that set and nothing else. This is
deliberate: the screen replaced a free-text event field that happily stored
typos which no producer ever emitted. The server enforces the same rule, so
subscriptions created through the API cannot drift either:
webhooks.update
runs assertKnownEventTypes on any eventTypes you send and rejects unknown
tokens.
Groups exist only in the UI. What lands on the endpoint row is a flat array of
patterns.
How event patterns are matched
The dispatcher matches a fired event type against the endpoint’s stored patterns using three forms:
The console applies the identical rule in reverse when you open Edit: a
group’s checkbox is pre-checked only when every type in that group is covered
by the row’s stored patterns. A row stored as
* therefore opens with all
groups checked.
Choosing groups vs ’*’
What the forms store depends on how many groups you check:- All groups checked collapses to
['*']. The endpoint then also receives event types that are added to the registry after you saved it. The dialog says so under the checkbox list. - Some groups checked stores the concatenated
typesof those groups as an explicit list. New event types added to the registry later are not delivered to that endpoint until you re-open Edit and save again. - No groups checked resolves to an empty array, which fails validation with “Pick at least one event group”. An empty subscription is never silently turned into “everything”.
* when your handler switches on the event type and ignores what it does
not recognise. Pick individual groups when your handler is strict, or when you
want to keep delivery volume to one endpoint narrow.
Endpoint URL rules
By default an endpoint URL must behttps://. Ticking On-prem /
private-network endpoint at create time sets allowPrivateEgress, which
permits http:// and RFC1918 targets for that row.
The flag is stored on the row and is what the server consults afterwards.
webhooks.update loads the existing endpoint and rejects an http:// URL with
http:// endpoints require private egress (on-prem targets only) unless the row
was created with private egress; the URL is then re-checked for deliverability
before the patch is applied. The Edit dialog mirrors this, so a row created
as public-only will not let you paste an http:// URL.
The optional Description is free text (max 300 characters) and is shown
under the URL in the table. Use it to record where deliveries land.
Signing secret and rotation
Each endpoint has its own HMAC secret (whsec_…). It is shown once — in the
dialog that appears right after create, and again after a rotate. The stored
row keeps only a sealed value plus a short preview, so there is no way to read
the secret back later.
Set the secret in your endpoint and verify the signature header on every
delivery; the secret dialog names the exact header.
Rotate mints a new secret and the previous one stops verifying
immediately — there is no overlap window. If your endpoint validates
signatures, update your side first, then rotate, or accept a gap in which
deliveries fail signature checks.
Testing an endpoint
Test callswebhooks.sendTest, which enqueues a signed test.ping envelope
directly to that endpoint. The test bypasses the subscription: it is delivered
regardless of which groups you checked.
The procedure then waits for the delivery worker’s verdict, polling the delivery
row for up to 12 seconds, and reports one of:
A test is audit-logged with its
ok flag and status code.
Endpoint health states
The Health column is derived, not stored as a single field:
A brand-new endpoint is Untested, not green. Green is earned by an actual
delivery — send a test if you want to confirm the URL before events start
flowing. The Last status column shows the most recent HTTP status code, or
— if there has never been one.
Pausing, resuming, and deleting
Pause flips the row tostatus: 'paused' through webhooks.update; the
endpoint receives no deliveries until it is resumed. Resume sets
status: 'active' and, in the same patch, clears consecutive_failures — so
resuming also clears an endpoint that the platform auto-paused for repeated
failures.
Delete soft-deletes the endpoint. Deliveries to it stop immediately and the
action cannot be undone. Endpoint create, update, secret rotation, and test are
all recorded in the org audit log.
Where deliveries are listed
This screen manages endpoints only. Individual deliveries — their payloads, statuses, and response codes — live on the Request logs page (/logs).
webhooks.list backs that view: it resolves the org’s streams endpoints
(plus org-wide rows whose vertical is null) and returns delivery rows for
them, newest first, optionally filtered by delivery status (pending,
delivering, delivered, dead). Full payloads are fetched separately for the
detail drawer rather than in the list.
Plan entitlement
Add endpoint is disabled when the org’s plan does not include the Streams product. The button explains this on hover; existing endpoints remain visible.Related
- Webhooks (platform) — signature construction, retry and backoff, refused destinations
- Authentication — API keys and org-scoped access to the control plane

