Polling an API to find out whether something changed is slow and wasteful. Webhooks turn it around: Clarion sends a signed request to your endpoint the moment something happens, and your system reacts.
The responsibility that comes with that is making your receiver trustworthy. It has to reject requests that didn’t come from Clarion, cope with the same event arriving twice, and answer fast enough that retries don’t pile up. This guide covers what to listen for, how to build a receiver that does those three things, and how to run it.
What you can react to
Clarion sends six events you can subscribe to:
| Event | Fires when |
|---|---|
milestone.completed | A milestone’s status first becomes completed. |
action_item.created | An action item is created. |
action_item.completed | An action item is completed. |
challenge.created | A challenge is raised. |
challenge.resolved | A challenge is resolved. |
metric.ingested | Values arrive through the ingest API, a push URL or a scheduled fetch. |
A seventh, webhook.test, is sent when you press Test on a subscription, and can’t be subscribed to.
Some things teams build with these:
- Post to a team chat channel when a milestone completes, so wins are seen outside the weekly meeting.
- Open a ticket in a support or engineering tracker when a challenge is raised on a particular team.
- Mirror action items into a task tool people already live in.
- Recalculate a dashboard or downstream report when new metric values land.
If you’d rather not host a receiver at all, an automation platform can catch the webhook for you. See Zapier, Make or n8n.
Setting up a subscription
Owners and Admins manage subscriptions in Settings → Integrations → Webhooks: an endpoint URL and the events it should receive. The signing secret is shown once, when the subscription is created. Store it with your other secrets straight away. See set up webhooks.
Rule 1: Verify every request
Each request carries these headers:
X-Clarion-Event: the event name.X-Clarion-Delivery: the delivery id.X-Clarion-Timestamp: when this attempt was sent, in Unix seconds.X-Clarion-Signature-V2:t=<timestamp>,v1=<hex>.
To verify, compute an HMAC-SHA256 with your signing secret over ${timestamp}.${rawBody} and compare it to v1 in constant time. Two details catch people out:
- Use the raw body, before your framework parses the JSON. Re-serialised JSON won’t match byte for byte.
- Check the timestamp. Reject anything outside a tolerance window, such as five minutes. Because the timestamp is inside the signature, a captured request stops working once it’s old.
There’s also an older X-Clarion-Signature header that signs the body alone. It’s deprecated: a captured request carrying it stays valid forever. Verify the V2 header and ignore the old one. The full code is in verify webhook signatures.
Rule 2: Deduplicate on the delivery id
Clarion retries failed deliveries, and a retry reuses the same X-Clarion-Delivery id. So does a manual redelivery from the app. The body’s createdAt is when the event happened and doesn’t change between attempts either.
Store the delivery ids you’ve handled, and skip any you’ve seen. Without this, a slow response that Clarion counts as a failure turns into two chat messages, two tickets or two task-tool entries.
Rule 3: Answer fast, work later
A delivery counts as failed on any non-2xx response, a 10-second timeout, or a redirect. Redirects are never followed. Clarion makes five attempts with exponential backoff starting at five seconds.
So the receiver’s job is: verify, record the delivery id, put the work on a queue, return 2xx. Do the slow part, like calling another API or writing to a database, afterwards. A receiver that does the work inline will time out under load and create the duplicates Rule 2 has to clean up.
Running it
Every attempt is recorded in Settings → Integrations → Recent deliveries, with the response code and body. That’s the first place to look when something didn’t arrive. Any delivery can be redelivered by hand. It keeps the original delivery id and is signed with a fresh timestamp, so your deduplication and verification both still work.
Use Test after any change to your endpoint, and before you subscribe to real events.
A launch checklist
- Signing secret stored as a secret, not in code.
- Signature verified against the raw body, with a timestamp tolerance.
- Delivery ids stored and checked.
- 2xx returned before slow work starts.
- Endpoint is the final URL, with no redirects.
- Test delivery succeeds and shows in Recent deliveries.
Common mistakes
Verifying the parsed body. The signature won’t match, and the tempting fix of skipping verification is the wrong one.
Verifying the deprecated header. It works, but it offers no protection against replays.
No deduplication. Retries are normal. Plan for them.
Doing the work before responding. Ten seconds goes quickly when you’re calling three other services.
Redirecting the endpoint. Moving your receiver behind a redirect makes every delivery fail. Update the subscription instead.
To push data the other way, see pushing metrics from your systems. To put your tool inside Clarion itself, see embedding your tool in Clarion.