⌘K
Back to all articles
API, CLI & MCP

Webhooks

Receive signed event callbacks for queries, alerts, insights, dashboards, and shares.

Updated May 30, 2026

Webhooks deliver workspace events to your endpoint in real time, so you can trigger downstream automation. Create and manage subscriptions in Webhooks settings.

Webhooks are available on the Scale plan and above.

Webhooks settings

Events

Subscribe to the events you care about:

  • query.completed, query.feedback
  • dashboard.created, dashboard.published, widget.added
  • alert.created, alert.fired, alert.resolved
  • insight.surfaced
  • data_source.connected
  • share.created

Delivery headers

Every delivery POSTs JSON to your endpoint with these headers:

HeaderValue
Content-Typeapplication/json
X-Queringo-EventThe event name (for example alert.fired).
X-Queringo-DeliveryA per-attempt id you can log for debugging.
X-Queringo-Signaturesha256=<hex digest> (see below).

Verifying deliveries

Each subscription has an HMAC-SHA256 signing secret prefixed whsec_, shown once when you create it. Compute the same signature on your side and compare it to the header in constant time. Reject the request if it does not match.

Node.js:

import crypto from "node:crypto";

function verify(rawBody, header, secret) {
  const expected = "sha256=" + crypto
    .createHmac("sha256", secret)
    .update(rawBody)        // use the raw bytes, not a re-serialised JSON
    .digest("hex");
  return crypto.timingSafeEqual(Buffer.from(header), Buffer.from(expected));
}

Python:

import hmac, hashlib

def verify(raw_body: bytes, header: str, secret: str) -> bool:
    expected = "sha256=" + hmac.new(secret.encode(), raw_body, hashlib.sha256).hexdigest()
    return hmac.compare_digest(header, expected)

Always verify the signature before acting on a webhook, and always sign over the raw request body as received. Re-serialising the JSON first will change the bytes and break the signature.

Test-fire a delivery

The settings page has a "test fire" button that sends a canned event (alert.test_fired by default) to your endpoint with a real signature, so you can validate the receiver before going live. Programmatically:

curl -X POST https://app.queringo.com/workspaces/{workspace_id}/webhook-subscriptions/{sub_id}/test \
  -H "Authorization: Bearer <your session token>" \
  -H "Content-Type: application/json" \
  -d '{"event": "alert.test_fired"}'

The delivery is sent inline so you get immediate feedback in the delivery history.

Retries

Failed deliveries are retried with exponential backoff (capped at about an hour between attempts) over a 24-hour retention window. Your endpoint should:

  • Respond 2xx quickly. Do heavy work asynchronously so deliveries are not held open.
  • Be idempotent. The same X-Queringo-Delivery id may arrive more than once if an earlier attempt timed out after your handler started.

The delivery history on the settings page shows the status code and timestamp for each attempt.

What's next

Embed dashboards with the Embed SDK.