# Webhooks

## What is it?

Webhooks automatically notify external systems about lab events — e.g., a CI
pipeline, a chat tool, or your own dashboard. As soon as something happens (a
test fails, a report is ready, …), TestLabIQ sends an HTTP POST to the URL you
configured.

## How to use it

1. **Setting one up:** Settings → Webhooks → *New webhook*. Choose a name,
   target URL (https recommended), and the desired events. The target URL must
   be publicly reachable — see *Common issues*.
2. **Events:**
   - `test.completed` — test case completed (passed or failed)
   - `test.failed` — test case failed (in addition to `test.completed`)
   - `sequence.completed` — all test cases in a sequence completed
   - `report.ready` — PDF report ready
   - `report.approved` — PDF report approved electronically (only then visible in the client portal)
   - `calibration.due` — equipment calibration is expiring / has expired
3. **Verifying the signature:** Every request carries an HMAC-SHA256
   signature over the raw body in the `X-TestLabIQ-Signature` header,
   computed with the webhook's signing secret (visible in the webhook list).
   This lets your endpoint verify that the call is genuine.
4. **Testing:** Via *Send test* you can trigger a sample delivery
   immediately.

## Common issues

- **"Nothing is arriving."** Check the last attempt in the delivery history
  (expandable under the webhook): if an HTTP status is shown, it was sent —
  then the issue is on your endpoint's side. If it shows *network error*, the
  URL was unreachable.
- **"Deliveries keep failing."** Failed deliveries are retried up to 4 times
  with increasing delay. On persistent failures, you'll be notified. Common
  causes: endpoint down, wrong URL, timeout, or your server not responding
  with 2xx.
- **"Signature verification fails."** The signature is computed over the
  **raw** request body — verify before JSON parsing and with the exact secret
  for this webhook (not another one's).
- **"Webhook is inactive."** Disabled webhooks send nothing; re-enable it in
  the list.
- **"The URL points to an internal address."** TestLabIQ calls your URL from
  its own server. Targets that are only reachable from inside a private
  network — `localhost`, `192.168.…`, `10.…`, `….local`, `….internal` — are
  therefore rejected: from our data centre they would be unreachable anyway,
  and the call would instead point at our own infrastructure. Use a publicly
  reachable address (e.g. via a reverse proxy or a tunnelling service). For the
  same reason the URL must not contain a username or password
  (`https://user:pass@…`); authenticate using the signature we send instead.
  Deliveries do not follow redirects (301/302) — configure the final URL
  directly.
- **"Blocked even though the address is correct."** On a self-hosted
  installation inside your own network, an internal target is exactly what you
  want. There, the environment variable `WEBHOOK_ALLOW_PRIVATE_TARGETS=true`
  lifts the check. In the hosted service it is deliberately not set.
- **Diagnosing via the support agent:** The AI support can look at recent
  delivery attempts directly (`get_webhook_deliveries` tool) and answer "why
  didn't my webhook arrive?" without a screenshot.

---

Source: https://www.testlabiq.com/en/help/webhooks
