vertical: 'quickdesk', so they receive the QuickDesk
event catalogue: signed POSTs when remote-desktop peers come online or go
offline, and when remote-control sessions connect or get denied.
Signing, retry behaviour and the delivery log are shared across every
ClutchCall vertical — see Webhooks. This page
covers what is specific to QuickDesk: which event tokens exist, how the
group picker maps onto them, and what a handler sees.
Event groups and types
The Event groups checklist on the webhooks screen is rendered fromwebhooks.catalog, the control-plane registry, not from a hardcoded list
in the console. That is deliberate: the picker can never offer a token
that no producer emits, and webhooks.create / webhooks.update reject
unknown tokens outright (assertKnownEventTypes). The registry is
therefore the authoritative list; the table below is the QuickDesk slice
of it.
Each group in the picker carries its own
label and description
straight from the registry, plus the list of types it expands to. Ticking
a group subscribes the endpoint to every type in that group.
test.ping is not part of any group. The Test button on each endpoint
row calls webhooks.sendTest, which delivers a signed test.ping to that
endpoint immediately and reports the HTTP status it got back. Use it to
prove your signature check works before real traffic arrives.
How event types are matched
An endpoint stores an array of patterns inevent_types. The dispatcher
matches a fired event against those patterns three ways, and the console
applies the identical contract when it decides which group badges to show
on a row:
- exact match —
session.deniedmatches onlysession.denied *— matches every event type- prefix glob
x.*—peer.*matchespeer.onlineandpeer.offline
- Selecting every group collapses to
*. The screen sendseventTypes: ['*']when all groups are ticked, which means the endpoint also receives event types added to the registry later. If you want a frozen contract, tick only the groups you handle. - Selecting nothing also stores
*. The screen falls back to['*']rather than creating an endpoint that can never fire.
webhooks.update with a new
eventTypes array; it is validated against the registry the same way as
on create.
Wiring a handler for peer presence
Subscribe to the peer presence group only, and your endpoint seespeer.online and peer.offline and nothing else — no session traffic,
and no future tokens from other groups.
Every delivery is a POST with a JSON body and a signature header. Verify
it over the raw request body, before parsing:
t and the raw body joined with a ., HMAC-SHA256
with the endpoint’s signing secret, hex encoded. The secret is returned
once — by webhooks.create at creation, and by
webhooks.rotateSecret on rotation. After that the console only shows
signing_secret_preview.
Rotation takes effect immediately: the previous secret stops verifying as
soon as webhooks.rotateSecret returns, so deploy the new secret on your
side first, or pause the endpoint while you swap it.
Session connected and denied
session.connected and session.denied are the two terminal outcomes of
a remote-control session request against a peer. Treat them as a pair:
session.connected— the session was established. This is the token to drive “session in progress” state, audit records, or an operator notification.session.denied— the request was refused instead of connecting. Nothing was established, so do not expect a latersession.connectedfor the same request.
Reading the exact payload of an event
This page names the event tokens; the field set inside each payload comes from the producer and is recorded verbatim on the delivery. Rather than coding against a guess, read a real one:- Create the endpoint with the groups you care about.
- Press Test on the endpoint row to confirm signature verification
works end to end (
webhooks.sendTestreports the HTTP status your server returned). - Trigger the real event, then open Recent deliveries and click into
the row. The delivery detail carries the full stored payload; the list
view carries only the metadata (
event_type,created_at,status,attempts,last_status_code,last_error).
delivered or dead state can be replayed with Redeliver, which
queues the same payload again — a convenient way to re-run a handler you
have just fixed.
Endpoint state you will see on the screen
Pressing Resume sets
status: 'active' through webhooks.update,
which also clears the consecutive-failure counter and the failing
auto-pause. Delivery rows themselves move through pending, delivering,
delivered and dead.
On-prem and private-network endpoints
By default an endpoint URL must behttps:// and must resolve to a
publicly deliverable address — webhooks.create runs a deliverability
check and rejects anything else with BAD_REQUEST. Tick On-prem /
private-network endpoint to set allowPrivateEgress, which permits
RFC1918 targets and http:// URLs. A plain http:// URL without that
flag is rejected on both create and update, and the flag stored on the row
— not the flag in the form — decides what a later URL change may point at.
Related
- Webhooks — signing, retries, and the delivery log shared by all verticals
- Authentication — API keys for the control-plane procedures behind this screen
- Telemetry — metrics and traces for the same events

