Skip to content

Webhooks

Webhooks let Mitr tell your other tools the moment something happens — a purchase, a signup, any custom event you already track. Instead of checking your dashboard or polling an API, the event shows up wherever you need it, seconds after it happens.

What you can build with it

A few real setups people use this for:

  • Get a Slack ping on every sale. Point a webhook at a Slack incoming-webhook URL, filter to your purchase event, and your team sees revenue land in real time — no dashboard-refreshing.
  • Sync signups into a CRM. Fire on signup, forward the payload to a small serverless function, and create the lead in HubSpot/Pipedrive/Airtable automatically instead of exporting CSVs.
  • Feed a data warehouse. If you already run BigQuery, Snowflake, or a Postgres warehouse, a webhook is the simplest way to stream Mitr events in alongside your other data, instead of waiting on a scheduled export.
  • Trigger no-code automation. Point a webhook at Zapier, Make, or n8n and build flows — a welcome email on signup, a Notion row per conversion — without writing a backend yourself.
  • Client reporting for agencies. Managing analytics for multiple client sites? Route each client's key conversions to their own Slack channel or dashboard, instead of them asking you to check.

How it works

In your dashboard, add a webhook with a destination URL and (optionally) the specific event names you care about — leave it blank to receive everything. From then on, every matching event sends an HTTP POST with a JSON body to that URL.

Delivery is decoupled from tracking: a webhook attempt never happens in the same request as the event being tracked, so a slow or temporarily unreachable endpoint on your end never slows down your site or app. If a delivery fails, Mitr retries automatically with increasing delays (1 minute, 5 minutes, 30 minutes, 2 hours, then 12 hours) before giving up — you can see the full delivery history, including any errors, right in the dashboard.

Setting one up

From the dashboard: Settings → Webhooks → Manage → Add webhook. Paste your destination URL, optionally list the event names to filter to, and save. Use the Send test button to fire an immediate test payload and confirm your endpoint is set up correctly before relying on it.

Payload shape

{
  "eventId": "3fae1c9e-...",
  "eventType": "purchase",
  "time": "2026-08-02T14:03:11.000Z",
  "path": "/checkout/success",
  "userHash": "a1b2c3d4...",
  "metadata": { "value": 49.99, "currency": "USD" },
  "siteId": "...",
  "workspaceId": "..."
}

userHash is already the same anonymised/hashed identifier Mitr stores internally — never a raw user ID, email, or device identifier. metadata is whatever custom properties you sent with the original event, already scanned and hashed for accidental PII at ingest.

Verifying requests came from Mitr

Every request includes an X-Mitr-Signature header — a hex-encoded HMAC-SHA256 of the exact request body, keyed with the signing secret shown in your webhook's settings. Recompute it on your end and compare before trusting the payload:

import hmac, hashlib

def verify(request_body: bytes, signature_header: str, secret: str) -> bool:
    expected = hmac.new(secret.encode(), request_body, hashlib.sha256).hexdigest()
    received = signature_header.removeprefix("sha256=")
    return hmac.compare_digest(expected, received)
const crypto = require('crypto');

function verify(rawBody, signatureHeader, secret) {
  const expected = crypto.createHmac('sha256', secret).update(rawBody).digest('hex');
  const received = signatureHeader.replace('sha256=', '');
  return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(received));
}

Limits

Free tier: 1 webhook endpoint, with delivery history kept for 7 days. Paid tiers: up to 5 endpoints, with delivery history kept as long as your plan's own data retention window. See pricing for details.

Have questions about integration or security? Drop us a line directly.