Skip to content

Alerts and webhooks

Be told when a number moves — by mail, or by a signed request to your own endpoint, with the delivery attempts on the screen.

3 min read Updated Suggest an edit

An alert watches one metric over a window and fires when it crosses a threshold you set. Alerts live on the project's Tracking page.

Create an alert

Choose New alert, then give it:

Field What it accepts
Name What you want to read when it fires.
Metric visitors, pageviews, events or bounce_rate.
Comparator above or below.
Threshold The number that fires it.
Recovery threshold The number that clears it again.
Window 5 minutes to 7 days (10,080 minutes).

A project keeps at most 20 alerts. Delete one before adding the twenty-first.

The recovery threshold must sit on the quiet side of the firing one. Otherwise the alert fires once and never clears — which looks exactly like an alert that works, right up to the moment you needed the second one.

The service evaluates alerts and delivers them. Its own columns — when the alert was last evaluated, when it last fired, the value it saw — are read-only here and shown beside the rule.

Send it to your own endpoint

Give the alert an https URL and every firing is also a POST to it.

JSON
{  "type": "alert.fired",  "alert_id": "0192f3c8-4a2e-7b61-9f3d-2c7a15e0b884",  "project_id": "0192f3c8-1b90-7c42-8a11-6f0d9e4c2a75",  "name": "Visitors dropped",  "rule": "visitors below 200 over 60 minutes",  "value": 184,  "window_minutes": 60,  "at": "2026-09-19T14:00:00Z"}

Send test delivers the same shape with "type": "test", so you can prove your receiver end to end before you need it.

A URL is refused unless it uses https, carries no credentials in it, has a host that resolves, and does not resolve to a private or local address.

Verify the signature

Every delivery carries a signature header over the raw body:

Plain text
X-Sightglass-Signature: t=1789401600,v1=6f3a…

v1 is HMAC-SHA256 of the timestamp, a full stop, and the exact bytes of the body, keyed with the alert's signing secret. It is the same scheme Stripe uses, so any Stripe verifier is a working reference.

PHP
$expected = hash_hmac('sha256', $timestamp.'.'.$rawBody, $secret);if (! hash_equals($expected, $signature)) {    abort(401);}

Compare in constant time, and check the timestamp is recent before you trust the body.

The signing secret is shown once, when the webhook is added. DataVisitors keeps it sealed and can never show it again; it is never listed on a screen and never leaves in a response. If you lose it, set the URL again to mint a new one.

Deliveries and retries

  • Each delivery gets 3 attempts and a 5-second timeout, with a short increasing pause between them.
  • Any 2xx is a success. A 4xx other than 408 or 429 is not retried — it will not answer differently next time.
  • The status, the time and the error of the last delivery are recorded on the alert, so a receiver that is down is visible on your screen rather than in ours.
  • A delivery is never sent unsigned. If the secret cannot be opened, the attempt is recorded with the reason and stopped.