Developers · Webhooks

Webhooks

MazeRank can POST signed JSON to your endpoint when something happens on a site: a new weekly plan, a fix marked done, a fix proven, a new wrong answer. Use it to feed Zapier, Make, your CRM or your own scripts. Webhooks and the Slack digest are part of Pro; CSV export is on every plan.

Setup

An owner or admin opens the site's Settings › Integrations, adds an HTTPS endpoint (public host, port 443 or 8443), picks events and saves. A signing secret (whsec_…) is created; reveal it there to configure your receiver, and rotate it any time. Send test event posts a ping. MazeRank never follows redirects.

Delivery

One POST per event, Content-Type: application/json. Answer with any 2xx within 10 s; process slow work after responding. Delivery is at least once, so dedupe on id (also in the MazeRank-Delivery header).

MazeRank-EventEvent type, e.g. fix.done or ping
MazeRank-DeliveryUnique delivery id, same as the body id; stable across retries
MazeRank-Signaturet=<unix seconds>,v1=<hex HMAC-SHA256>
User-AgentMazeRank-Webhooks/1.0
Body
{
  "id": "dlv_8f2c…",
  "type": "fix.done",
  "created_at": "2026-10-22T09:12:03.000Z",
  "api_version": "2026-10-22",
  "site": {
    "id": "jh7…",
    "name": "MyDermaCare"
  },
  "data": {
    "fix_id": "jd7…",
    "type": "article",
    "title": "Publish a page for “dermatologist online Portugal”",
    "published_url": "https://example.com/teleconsulta",
    "done_at": "2026-10-22T09:12:03.000Z"
  }
}

Signatures

The signature is HMAC-SHA256 with your secret over `${t}.${rawBody}`. Compare in constant time and reject timestamps older than 5 minutes to stop replays. After a rotation, only the new secret signs.

Node
import { createHmac, timingSafeEqual } from "node:crypto";

// rawBody: the exact bytes received (do not re-serialise the JSON)
export function verifyMazeRank(rawBody, header, secret, toleranceSec = 300) {
  const t = /t=(\d+)/.exec(header ?? "")?.[1];
  const v1 = /v1=([0-9a-f]{64})/.exec(header ?? "")?.[1];
  if (!t || !v1 || Math.abs(Date.now() / 1000 - Number(t)) > toleranceSec) return false;
  const want = createHmac("sha256", secret).update(`${t}.${rawBody}`).digest("hex");
  return timingSafeEqual(Buffer.from(want), Buffer.from(v1));
}

Retries

Network errors, timeouts, 408, 429 and 5xx are retried: 1 min, 5 min, 30 min, 2 h, 6 h after each failure, 6 attempts in all (about 8.5 hours), then the delivery is marked failed. Other 4xx answers and redirects fail at once. The last 25 deliveries, with status, attempts and the response code, are in the delivery log under Settings › Integrations, where any finished delivery can be sent again.

Events

plan.created

A new weekly plan is built (Mondays, after the weekly check).

data
{
  "week_of": "2026-10-19",
  "tasks": [
    {
      "task_id": "s:jd7…",
      "type": "fix",
      "kind": "article",
      "slot": "build",
      "effort_minutes": 45,
      "who": "you_ai"
    }
  ]
}

fix.done

A fix is marked done, in the app, over the API or by an agent.

data
{
  "fix_id": "jd7…",
  "type": "article",
  "title": "Publish a page for “dermatologist online Portugal”",
  "published_url": "https://example.com/teleconsulta",
  "done_at": "2026-10-22T09:12:03.000Z"
}

fix.proven

A done fix or correction is confirmed by the AI engines (the proof receipt is ready).

data
{
  "task_id": "s:jd7…",
  "type": "fix",
  "fix_id": "jd7…",
  "proven_at": "2026-11-02T06:00:00.000Z",
  "receipt_url": "https://mazerank.com/proof/…"
}

wrong_answer.found

A new wrong answer about the business is found in an AI engine.

data
{
  "correction_id": "k17…",
  "field": "hours",
  "claim": "Closed on Saturdays",
  "truth": "Open Saturdays 9:00–13:00",
  "verdict": "wrong",
  "severity": "high",
  "engines": [
    "chatgpt"
  ],
  "likely_sources": [
    "https://directory.example/listing"
  ]
}

Slack digest

Paste a Slack incoming-webhook URL (https://hooks.slack.com/services/…) in Settings › Integrations. Every Monday after the weekly check, MazeRank posts the week's plan, the month's wins and new wrong answers to that channel, in the site's language, at most once a week. The URL is stored masked in the app; disconnect any time.

CSV export

Settings › Integrations › Exports downloads AI answers, fixes, claims and wrong answers, proofs and the week's plan as UTF-8 CSV (with BOM, opens cleanly in Excel), up to 5,000 rows each. Over the API: GET /v1/sites/{site_id}/export/{answers|fixes|claims|proofs|plan}.csv, each needing the matching read scope (see the API reference).