Home
Pricing
Platform Blog About Contact FAQ Partners
Sign in Start free
Webhooks

Any alert, any endpoint,
your integration.

Send a signed JSON payload to any HTTPS endpoint when a monitor fires: customisable fields, automatic retries with exponential backoff, and delivery logs so you can debug every event.

Free tier included No credit card 2-minute setup
Site Qwality monitors list with status and sparklines

Build any integration on top of webhooks.

Webhooks are the universal integration primitive. Whether you're routing alerts into a homegrown incident tool, creating Jira tickets, or feeding a Datadog event stream, the webhook endpoint is where Site Qwality hands off to your systems.

JSON payload on every event

Receive a structured JSON body with the monitor id, the status, the URL that was checked, the HTTP code, the failure reason and the per-phase timing on every down and recover event.

HMAC-SHA256 signatures

Every delivery includes an X-SiteQwality-Signature header. It is an HMAC-SHA256 over the delivery id, the timestamp and the raw request body, joined with full stops, keyed with your endpoint's signing secret. The timestamp is inside the signature, so a captured delivery cannot be replayed against you.

Automatic retries with backoff

A failed delivery is retried with exponential backoff, up to five retries over 30 minutes, before it is marked failed. That is six deliveries in total: the first attempt and five retries.

Customisable payload fields

Choose which fields appear in the payload, add custom metadata, or filter events by severity so your receiver only handles what it needs.

Delivery log and inspector

Every delivery is logged with the request we sent, the response status code, an extract of the response body and how long it took. Records are kept for 30 days. Read them and replay any delivery through the API.

Multiple endpoints per monitor

Send the same event to multiple endpoints: route one alert to a PagerDuty webhook and a custom audit log service simultaneously.

Reliable delivery

Retries so you never
miss an event.

If your endpoint is unreachable or returns a 5xx, Site Qwality retries at 10 seconds, 30 seconds, 2 minutes, 8 minutes and 30 minutes after the first attempt. A 4xx is not retried: if your endpoint returns 404 we tell you rather than sending the same request five more times. Every attempt is logged with the HTTP status.

  • The first attempt, then up to five retries with exponential backoff
  • Every attempt logged with its status code and an extract of the response body
  • Replay any past delivery through the API
app.siteqwality.com / webhooks / deliveries
POST /hooks/incident-tool DeliveredLIVE
ATTEMPTS2
FINAL STATUS200
SIGNEDno
attempt 1timeout
attempt 2200 OK
payload size1.2 KB
signaturenone sent
Full event payload

Every field your
integration needs.

The payload is the check result itself, under a data key: the monitor id, the status, the URL that was checked, the HTTP code, the failure reason, the timestamp, and the per-phase timing breakdown. Enough to create a ticket or route an on-call page with no follow-up API calls.

  • Monitor id, status, URL, HTTP code and failure reason in one payload
  • ISO-8601 timestamps and consistent field names across events
  • Custom key-value metadata you define per endpoint
example payload{
  "data": {
    "http_job_id": "8f1c3a92-5d47-4e1b-9c60-2ab7d5f80e31",
    "status": "failed",
    "request_uri": "https://api.acme.com/checkout",
    "response_http_code": 503,
    "failure_reason": "status",
    "check_region": "aws-us-east-1",
    "request_duration_ms": 184,
    "ttfb_ms": 171,
    "created_at": "2026-03-14T09:26:53Z"
  }
}
Verifying a delivery

The signed string,
and how to check it.

The signature covers {delivery_id}.{timestamp}.{raw request body}, not the body on its own. Both the id and the timestamp arrive as headers, and both are inside the MAC: the id because it is your dedupe key, the timestamp because a signature without one is replayable forever. Check staleness before you check the MAC, and compare in constant time.

  • Sign the exact bytes we sent, before any JSON parsing
  • Use the secret verbatim: no base64 decode, no prefix stripping
  • Expect two space-separated entries for 24 hours after a secret rotation
verify.js// rawBody must be the exact bytes we sent, before JSON.parse.
const id   = req.headers['x-siteqwality-delivery'];
const ts   = req.headers['x-siteqwality-timestamp'];
const sigs = req.headers['x-siteqwality-signature'].split(' ');

// Reject a stale delivery BEFORE checking the MAC.
if (Math.abs(Date.now() / 1000 - Number(ts)) > 300) return reject();

const expected = 'v1=' + crypto
  .createHmac('sha256', secret)
  .update(`${id}.${ts}.${rawBody}`)
  .digest('hex');

// Two entries for 24h after a rotation. Constant time.
const ok = sigs.some(s => s.length === expected.length &&
  crypto.timingSafeEqual(Buffer.from(s), Buffer.from(expected)));
5

retries before a delivery is marked failed

$0

webhooks on every plan, including free

30d

every delivery logged with the full request and an extract of the response

15s

request timeout on every delivery attempt, after which we give up on that attempt

FAQ

The signed string is {delivery_id}.{timestamp}.{raw request body}, joined with full stops, and the header value is v1= followed by the hex HMAC-SHA256 of that string under your endpoint's signing secret. The secret is used exactly as shown to you, with no base64 decoding and no prefix stripping. The delivery id and the timestamp arrive in X-SiteQwality-Delivery and X-SiteQwality-Timestamp, and both are inside the MAC. Signing over the body alone would leave a captured delivery replayable, which is why the sentence that used to sit here was wrong and would have produced a verifier that never matched. Check the timestamp is within five minutes before you check the MAC, and expect more than one space-separated v1= entry for the 24 hours after you rotate a secret. The snippet above this FAQ does all of it.

Seven events fire: monitor.down, monitor.recover, incident.created, incident.resolved, tls.expiring, dns.expiring and page_speed.degraded. All seven are on by default and you can filter them per endpoint, by event or by severity, so a receiver only handles what it needs.

Site Qwality retries at 10 seconds, 30 seconds, 2 minutes, 8 minutes and 30 minutes after the first attempt. Read those as offsets from the first attempt, not as gaps between retries: the last one lands exactly 30 minutes in. That is six deliveries at most, the first attempt plus five retries, and a delivery that has not succeeded 30 minutes after the first attempt is marked failed. You can then replay it from the delivery log.

Yes, through the API. The delivery log holds every attempt with the request we sent, the response status code, an extract of the response body and how long it took, for 30 days. A replay is a new delivery with a new id, a fresh timestamp and a fresh signature under your current secret, so it resends what was sent rather than what today's settings would produce.

Yes. Webhooks are included on every plan, including the free tier. There is no limit on the number of endpoints or deliveries on paid plans.

Start free. No credit card.

Uptime, cron, synthetic, logs, RUM, incidents, and status pages. Free tier on every product.