DocsWebhooks & Integrations

Webhooks & Integrations

Send events to Slack, Discord, Zapier, Make, n8n or your own endpoint, and export data as CSV or JSON.

Open Setup → Integrations to connect a webhook, Slack or Discord. Only the project owner can manage integrations. Each one has its own event checkboxes, an on/off switch, a Send test button and the result of the last delivery.

  • Events: feedback.created, feedback.critical, feedback.status_changed and survey_response.created. Spam never fires events.
  • Slack and Discord use an incoming-webhook URL, so no app install or OAuth is needed. With both New and Critical feedback on, a critical report posts one 🚨 alert instead of two messages.
  • Webhook POSTs JSON to any https URL, which is how Zapier, Make and n8n connect (use their “catch webhook” trigger). Requests time out after 5 seconds and are retried once on a network error or 5xx.

Webhook payload

JSON
{
  "id": "evt_…",
  "type": "feedback.created",
  "createdAt": "2026-09-27T10:00:00.000Z",
  "project": { "id": "…", "name": "Acme", "slug": "acme" },
  "data": {
    "id": "…",
    "type": "issue",
    "status": "new",
    "message": "The checkout button does nothing",
    "userName": "Ada Lovelace",
    "userEmail": "ada@example.com",
    "pageUrl": "https://example.com/checkout",
    "isCritical": false,
    "metadata": { "plan": "pro", "userId": "u_123" },
    "createdAt": "2026-09-27T10:00:00.000Z",
    "url": "https://www.supafeedback.com/project/acme"
  }
}

feedback.status_changed adds previousStatus. survey_response.created sends surveyId, surveyName, rating and comment instead of the feedback fields. Internal notes are never included.

Verifying signatures

Every webhook request has X-SupaFeedback-Event, X-SupaFeedback-Delivery and X-SupaFeedback-Signature headers. The signature is an HMAC-SHA256 of <t>.<raw body> using the signing secret shown in Setup. Compute it over the raw request body, before JSON parsing.

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

// header: X-SupaFeedback-Signature, e.g. "t=1790000000,v1=5f2b…"
export const verifySupaFeedback = (rawBody, header, secret) => {
  const parts = Object.fromEntries(
    header.split(",").map((part) => part.split("=")),
  );
  const expected = createHmac("sha256", secret)
    .update(`${parts.t}.${rawBody}`)
    .digest("hex");
  const fresh = Math.abs(Date.now() / 1000 - Number(parts.t)) < 300;
  return (
    fresh &&
    expected.length === parts.v1?.length &&
    timingSafeEqual(Buffer.from(expected), Buffer.from(parts.v1))
  );
};

Export

Choose Export in the inbox toolbar to download feedback as CSV or JSON using the current folder, filters and search. Each survey has Export responses too. Exports include metadata and are capped at 50,000 rows. Any project member can export.