Webhooks & workflows

Workflows fire on scan events (every scan, first scan, threshold, blocked/expired) and on daily checks (not scanned for N days, expiring within N days, fewer than N scans).

Actions: webhook, Slack incoming webhook, email, Google Sheet (Apps Script web app URL that appends a row), add tag, pause code.

Verifying a webhook Compare header `x-qrforge-signature` with the secret you set on the action. Payload example:

{ "event": "scan", "qr": { "id": "…", "name": "GA-A-01", "slug": "k7m2p9q", "tags": ["rack"], "meta": { "Section": "GROUND FLOOR" }, "scan_count": 12 },
  "scan": { "scanId": 5521, "country": "IN", "device": "mobile", "outcome": "redirect" }, "at": "2026-09-06T08:00:00Z" }

Google Sheets in 2 minutes Extensions → Apps Script → paste `function doPost(e){const b=JSON.parse(e.postData.contents);SpreadsheetApp.getActiveSheet().appendRow([b.at,b.qr.name,b.scan.country,b.scan.device]);return ContentService.createTextOutput("ok");}` → Deploy as web app (anyone) → use the URL in a **Google Sheet** action.