Log Simrix Monitor alerts to a Google Sheet

Simrix Monitor does not write to Google Sheets directly. A webhook pointed at a relay can append a row for every alert, which gives you the delivery history the product does not keep. This page covers the setup and which fields to map.

There is no native integration for this yet. Alerts get there through a webhook pointed at a relay you control. The steps below set that up.

Steps

  1. Create a sheet with a header row. A good starting set is timestamp, event, monitor, site URL, status, failure summary and check id.
  2. Create a relay that can receive a webhook and append a row: Zapier and Make both have a Google Sheets step.
  3. In Simrix Monitor, open Account → Webhooks, choose Add webhook, and paste the relay's URL.
  4. Pick the events and save, copying the signing secret before you leave the page.
  5. In the relay, verify the signature, then map the body's fields onto your columns.

Why a sheet is more useful here than it sounds

Simrix Monitor keeps the record of every check, but it does not keep a log of alerts that were sent, and webhook deliveries are not recorded at all. A sheet gives you that history on your own side.

It also makes the pattern visible. One failure is an incident; the same monitor failing every Tuesday afternoon is a cause, and that is far easier to notice in rows than in an inbox.

Which fields are worth a column?

timestamp and event give you when and what. monitor.name and monitor.url say which check and where. run.status and run.failureSummary say what happened. run.id lets you find the check in the app later.

One caveat on screenshots: run.screenshotUrl is a path rather than a full address, and opening it needs a signed-in session, so a link in a shared sheet will not open for someone outside your workspace.

What does Simrix Monitor send?

A single JSON POST per event. Here is a real body for a failed check.

{
  "event": "monitor_failed",
  "timestamp": "2026-09-14T14:03:11.482Z",
  "workspaceId": "clz9a1b2c3d4e5f6g7h8i9j0",
  "monitor": {
    "id": "clz8m0n1o2p3q4r5s6t7u8v9",
    "name": "Checkout smoke test",
    "type": "page_check",
    "url": "https://shop.example.com/checkout"
  },
  "run": {
    "id": "clz7r0u1n2i3d4e5f6g7h8i9",
    "status": "failed",
    "changeDetected": false,
    "aiSummary": "We could not find “#place-order” on the page at step 3 of 6. It may have been renamed or moved, or the page may not have got that far.",
    "failureSummary": "We could not find “#place-order” on the page at step 3 of 6. It may have been renamed or moved, or the page may not have got that far.",
    "failureReasonCode": "element_not_found",
    "durationMs": 31204,
    "httpStatus": 200,
    "screenshotUrl": "/api/artifacts/clz7r0u1n2i3d4e5f6g7h8i9/screenshot.png",
    "diffScreenshotUrl": null,
    "shareUrl": "https://simrixmonitor.com/r/Zq8nT2xK9pLm4vR7wYbC1dF3hJ5kN6sQ8tU0xW2yA4E"
  }
}

Which events can fire?

Event When it fires
monitor_failed A scheduled check on a workflow monitor failed.
monitor_recovered A workflow monitor passed again after a failure.
change_detected A change monitor found a meaningful difference from its baseline.

What is in the body?

Field Type Notes
event string One of the three event names.
timestamp string ISO 8601, set when the request is sent, not when the check ran.
workspaceId string Your workspace.
monitor.id string Use this to correlate with your own records.
monitor.name string The monitor's name as you set it.
monitor.type string The monitor's kind, for example page_check or change_monitor.
monitor.url string The URL the check started from. Empty string if none was set.
run.id string The check's id.
run.status string For example passed or failed.
run.changeDetected boolean True only on change_detected.
run.aiSummary string or null The plain-English summary, when one was produced.
run.failureSummary string or null Why the check failed. Null on success events.
run.durationMs number or null How long the check took.
run.httpStatus number or null The response code of the final page.
run.screenshotUrl string or null A path, not a full URL. Prefix it with your Simrix Monitor address, and note it needs a signed-in session to open.
run.diffScreenshotUrl string or null The highlighted difference image. Only on change_detected.
run.shareUrl string or null A public link to this check's evidence, when the monitor has shareable reports switched on. Opens with no sign-in, so this is the link to forward. Null when sharing is off for that monitor.

Which headers arrive?

Header Value Notes
Content-Type application/json The body is always JSON.
X-Simrix-Signature sha256=<hex digest> HMAC-SHA256 of the raw request body, keyed with your signing secret.
X-Simrix-Event monitor_failed The same value as the body's event field, so you can route before parsing.
User-Agent Simrix-Monitor-Webhook/1.0 Fixed. Useful for filtering your own logs.

How do you verify the signature?

The signature is an HMAC-SHA256 of the raw request body, keyed with your signing secret and written as lowercase hex behind a sha256= prefix.

import crypto from "node:crypto";

// Sign the RAW body. Re-serialising parsed JSON will not match.
function isFromSimrixMonitor(rawBody, header, secret) {
  const expected =
    "sha256=" + crypto.createHmac("sha256", secret).update(rawBody).digest("hex");
  const a = Buffer.from(expected);
  const b = Buffer.from(header ?? "");
  return a.length === b.length && crypto.timingSafeEqual(a, b);
}

What should your receiver expect?

  • Delivery is attempted once. A non-2xx response, a connection error or a timeout is logged and dropped. There is no retry, no backoff and no dead-letter queue, so treat a missed delivery as possible and reconcile from the app when it matters.
  • The timeout is 10 seconds for the whole request. Acknowledge quickly and do your own work afterwards, rather than processing before you respond.
  • The signature covers the raw body only. No timestamp is included, so there is no replay protection built in. If that matters, record run.id and ignore ids you have already handled.
  • Change monitors only fire change_detected. A change monitor that errors does not send monitor_failed, and change monitors never send monitor_recovered. Subscribing to monitor_failed will not tell you a change monitor is broken.
  • Failure and recovery webhooks follow the email toggles. Turning off Failure alerts or Recovery alerts on the notifications page turns off the matching webhook as well.
  • Only scheduled checks send anything. Running a check by hand to try something out fires no webhook and sends no email.
Start free trial

14 days, no card required.

Frequently asked questions

Can Simrix Monitor write to a sheet without a relay?

No. There is no Google Sheets integration. Webhooks and email are the only delivery channels, so a relay does the writing.

Will the sheet capture every alert?

Almost, but not guaranteed. Deliveries are attempted once with no retry, so an outage at the relay loses that row rather than replaying it later.

Can I export check history instead?

Not today. There is no CSV or PDF export of check history in the app, which is part of why a sheet fed by webhooks is useful.

Last updated