Feedback, programmable
A lightweight website SDK, a REST API, GraphQL and signed webhooks. Put surveys anywhere and send the answers everywhere.
Website SDK
Paste the snippet before </body>. Your public key is in Settings → Installation. It is safe to expose: it can only show active campaigns and submit answers.
Popups and inline widgets then appear according to each campaign's URL rules, targeting, sampling and frequency settings, with no redeploy when you change a survey.
- Works with any stack: plain HTML, React, Next.js, Vue, Webflow, WordPress (plugin available)
- Answers are saved progressively, so partial responses are never lost
- Identify signed-in users to link feedback to accounts
- Hosted survey links need no code at all
index.html
<!-- FeedbackBuddy -->
<script src="https://fb2-app.admin.eclotodesigns.com/sdk/v1.js"
data-key="pk_…" async></script> app.js (optional)
// Link answers to a signed-in user
FeedbackBuddy.identify({
externalId: 'user_42',
email: 'maya@example.com',
attributes: { plan: 'pro', seats: 12 },
})
// Open a specific campaign, e.g. from a "Give feedback" button
FeedbackBuddy.show('<campaign-id>') REST API
Base URL https://fb2-app.admin.eclotodesigns.com/api/v1. Authenticate with an org API key as a bearer token. Keys are created in Settings → API keys with the scopes you choose.
API access and webhooks are included in Pro.
Fetch this week's responses
curl -G https://fb2-app.admin.eclotodesigns.com/api/v1/responses \
-d campaignId=<campaign-id> -d from=2026-09-01 \
-H "Authorization: Bearer fb_live_…" | Method | Endpoint | Description |
|---|---|---|
| GET | /api/v1/campaigns | List campaigns |
| GET | /api/v1/campaigns/:id | Get one campaign with its questions |
| GET | /api/v1/responses | List responses. Filter by campaignId, from, to; paginate with cursor |
| POST | /api/v1/responses | Submit a response server-side |
| POST | /api/v1/contacts | Create or update a contact (email, externalId, attributes) |
| POST | /api/v1/events/trigger | Trigger an email automation for a contact |
Webhooks
Subscribe an HTTPS endpoint to events and we POST a JSON payload as they happen. Every request is signed so you can verify it came from FeedbackBuddy.
Header: X-FeedbackBuddy-Signature: t=<timestamp>,v1=<signature>, where the signature is the hex HMAC-SHA256 of timestamp + "." + raw body using your endpoint secret.
Events
response.createdresponse.completedcampaign.createdcampaign.updatedcampaign.deletedmember.joinedorg.plan_changed
verify.ts (Node / Bun)
import { createHmac, timingSafeEqual } from 'node:crypto'
export function verify(rawBody: string, header: string, secret: string) {
const parts = Object.fromEntries(header.split(',').map((p) => p.split('=')))
const expected = createHmac('sha256', secret)
.update(parts.t + "." + rawBody)
.digest('hex')
const got = Buffer.from(parts.v1 ?? '')
const fresh = Math.abs(Date.now() / 1000 - Number(parts.t)) < 300
return fresh && got.length === expected.length
&& timingSafeEqual(Buffer.from(expected), got)
} GraphQL
The dashboard runs on a typed GraphQL API. Use it when you need reports, filters and nested data in a single request. Server-side integrations should prefer the REST API, which is versioned and scoped by API key.
Need something that is not covered? Email hello@feedbackbuddy.app.
Get your API key
Create a free account, grab your public key and add your first survey in minutes.