Developers

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_…"
REST endpoints
MethodEndpointDescription
GET/api/v1/campaignsList campaigns
GET/api/v1/campaigns/:idGet one campaign with its questions
GET/api/v1/responsesList responses. Filter by campaignId, from, to; paginate with cursor
POST/api/v1/responsesSubmit a response server-side
POST/api/v1/contactsCreate or update a contact (email, externalId, attributes)
POST/api/v1/events/triggerTrigger 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.created
  • response.completed
  • campaign.created
  • campaign.updated
  • campaign.deleted
  • member.joined
  • org.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.