How to set up webhooks

4 min read

Webhooks let you receive real-time HTTP POST requests every time feedback is submitted. Send events to your own backend, a Zapier catch hook, Notion API, or any service that accepts JSON over HTTPS.

Before you start

  • A publicly accessible HTTPS endpoint that returns a 2xx status code.
  • A FeedbackBar project with at least one active widget.

Step 1 — Add a webhook in FeedbackBar

  1. In your dashboard, open your project and go to the Integrations tab.
  2. Click Webhook in the available integrations list.
  3. Enter your endpoint URL (must be HTTPS).
  4. Click Save.

Step 2 — Understand the payload

Every webhook request is a POST with a JSON body and Content-Type: application/json header.

POST https://your-api.com/webhooks
{
  "event": "feedback.created",
  "timestamp": "2025-07-14T09:32:11Z",
  "data": {
    "id": "fb_r4k9m2",
    "widgetId": "wgt_k8m2x9",
    "projectId": "prj_x7n3q1",
    "sentiment": "negative",
    "comment": "Checkout flow is confusing",
    "rating": 2,
    "pageUrl": "/checkout/step-2",
    "sessionId": "sess_a1b2c3",
    "email": "user@example.com",
    "createdAt": "2025-07-14T09:32:11Z"
  }
}

Payload fields

event— Always feedback.created for now. More event types coming soon.
timestamp— ISO 8601 UTC timestamp of the event.
data.sentimentpositive or negative.
data.comment— Free-text comment (may be empty).
data.rating— 1–5 star rating (present only if star rating is enabled).
data.pageUrl— Page path where feedback was submitted.
data.email— User email (present only if email collection is enabled and provided).

Step 3 — Configure delivery options

Click the webhook integration row to open settings. Under Settings → Edit:

Event filters

Choose whether to fire on positive feedback, negative feedback, or both. Filtering at the source reduces noise and saves your endpoint from unnecessary traffic.

Widget scope

By default the webhook fires for all widgets in the project. To limit it to specific widgets, click Edit next to the Widgets section and check only the ones you want.

Step 4 — Send a test event

At the bottom of the integration panel, click Send Test. This sends a sample payload to your endpoint immediately. If you don't receive it within 10 seconds, check:

  • The integration status is Active.
  • Your endpoint is publicly reachable over HTTPS.
  • Your endpoint returns a 2xx status code.

Check the Logs tab in the integration panel for delivery status and error details.

Retry behavior

If your endpoint returns a non-2xx status or times out (30 s), FeedbackBar retries with exponential backoff:

  • 1st retry — after 1 minute
  • 2nd retry — after 5 minutes
  • 3rd retry — after 30 minutes

After 3 failed attempts the delivery is marked as failed in the Logs tab. No further retries are attempted for that event.

Verifying webhook signatures

Every webhook request includes an X-FeedbackBar-Signature header containing an HMAC-SHA256 signature of the request body. Your signing secret is shown once when you create the webhook — store it securely.

const crypto = require('crypto');

function verifySignature(body, signature, secret) {
  const expected = crypto
    .createHmac('sha256', secret)
    .update(body, 'utf8')
    .digest('hex');
  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expected)
  );
}
Always verify the signature before processing the payload to prevent spoofed requests.

Pausing or deleting the webhook

  • Pause — toggle the Status switch off in the Settings tab. Events are not queued while paused.
  • Delete — scroll to the Danger Zone section and click Delete. This is permanent and revokes the signing secret.