Feedback webhooks

When Hosted posts appear or change status, you may want Slack, Linear, or your own worker notified, without shipping customer prose through the wire.

Feedback webhooks carry operational identifiers only. Configure an HTTPS endpoint in the dashboard (webhooks are dashboard-only, not MCP).

Events

EventWhen
feedback.post_createdHosted post created. Data: boardId, postId, authorId.
feedback.status_changedHosted status change. Data: ids plus fromStatus / toStatus.

Envelope fields also include workspaceId, productId (feedback), and timestamp. Docs: post_created, status_changed.

BYO adapters keep content on your backend and do not emit these Bootstrapware Feedback webhooks for your store.

Signature

Deliveries POST JSON and sign the raw body with HMAC-SHA256. The hex digest is sent as header X-Bootstrapware-Signature. A failed delivery is retried once.

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

function verifyBootstrapwareSignature(
  rawBody: string,
  header: string | null,
  secret: string,
) {
  if (!header) return false;
  const expected = createHmac("sha256", secret).update(rawBody).digest("hex");
  const a = Buffer.from(expected, "hex");
  const b = Buffer.from(header, "hex");
  if (a.length !== b.length) return false;
  return timingSafeEqual(a, b);
}

Verify before JSON.parse. Use the endpoint secret from the dashboard. Prefer timingSafeEqual over string equality.

Example Next.js handler sketch

// app/api/webhooks/feedback/route.ts
export async function POST(req: Request) {
  const rawBody = await req.text();
  const ok = verifyBootstrapwareSignature(
    rawBody,
    req.headers.get("X-Bootstrapware-Signature"),
    process.env.FEEDBACK_WEBHOOK_SECRET!,
  );
  if (!ok) return new Response("invalid signature", { status: 401 });

  const envelope = JSON.parse(rawBody) as {
    event: string;
    data: Record<string, string>;
  };
  // Fetch Hosted content via your secret-key dashboard flow if needed, 
  // the webhook never includes title/body.
  void envelope;
  return new Response("ok");
}

Pitfalls

  • Verifying a re-serialized JSON body, always HMAC the exact raw bytes received.
  • Expecting title/body in the payload, fetch Hosted content separately if you need prose.
  • Configuring webhooks via MCP, endpoints are dashboard-only.

Related: Webhooks overview · post_created · status_changed · Moderation · Security