Documentation
Everything you need to install, configure, and get the most out of BetterFeedback.
Installation
Add the BetterFeedback snippet to your application. You'll find your public key in Settings → Installation Snippet after signing in.
Step 1: Add the script tag
Place this before the closing </body> tag on every page where you want to collect feedback.
<script src="https://app.betterfeedback.io/snippet.js?key=YOUR_PUBLIC_KEY"></script>
Step 2: Initialize with user attributes (recommended)
Call BetterFeedback.init() after the snippet loads. Pass any attributes you want to use for segmentation.
<script>
BetterFeedback.init({
user_id: '12345',
email: 'user@example.com',
plan: 'pro',
company: 'Acme Corp',
role: 'admin'
});
</script>
You can also pre-set attributes before the script loads:
<script>
window.BetterFeedbackAttributes = {
user_id: '12345',
plan: 'pro'
};
</script>
<script src="https://app.betterfeedback.io/snippet.js?key=YOUR_PUBLIC_KEY"></script>
Tip: Install the snippet once. Call BetterFeedback.init() after page load and whenever user data changes (e.g., after login).
Identifying users
BetterFeedback automatically generates a unique identifier for each visitor, stored in localStorage. To link survey responses to your own user records, pass a unique identifier attribute.
Unique identifier attribute
In Settings → Snippet Configuration, set the Unique identifier attribute to the key you pass in init() (e.g., user_id or email). This links the anonymous BetterFeedback identity to your user.
Custom attributes
Any key/value pairs you pass to init() are stored as custom attributes and can be used for segmentation. Common attributes:
| Attribute | Example | Purpose |
|---|---|---|
| user_id | "12345" | Link to your user records |
| "user@example.com" | Email follow-up surveys | |
| plan | "pro" | Segment by pricing tier |
| company | "Acme Corp" | Group by organization |
| role | "admin" | Target specific user roles |
Survey types
BetterFeedback supports four survey types, each designed for a different use case.
NPS (Net Promoter Score)
Asks users to rate on a scale of 0–10 how likely they are to recommend your product. Calculates promoters (9–10), passives (7–8), and detractors (0–6). Includes an optional follow-up question for open-ended feedback.
CSAT (Customer Satisfaction)
Asks users to rate their satisfaction on a scale of 1–5, from "Very dissatisfied" to "Very satisfied." Includes an optional follow-up question for qualitative feedback.
Custom Survey
Define your own questions with custom response options. Build multi-question surveys tailored to your needs. Available on Pro and Studio plans.
In-App Notification
Display announcements, messages, or feature updates directly in your app. No rating or response required — purely informational.
Display positions
Control where surveys appear in your app. Choose the position when creating a survey.
| Position | Behavior |
|---|---|
| Centered modal | Survey appears as a centered modal with an overlay. Page scrolling is locked until the survey is dismissed or completed. |
| Bottom banner | Sticky bar at the bottom of the viewport. No overlay — users can continue interacting with your app. |
| Bottom right corner | Floating widget in the bottom-right corner. Non-intrusive — doesn't block any content. |
Delivery methods
Choose how your survey reaches users.
In-app only
Survey appears in the app via the JavaScript snippet. Users must be active in your app to see it.
In-app, then email
Shows the survey in-app first. If the user doesn't respond within a configurable delay, a follow-up email is sent (requires an email attribute).
Email only
Skip the in-app display entirely. The survey is delivered by email only. Useful for users who aren't actively using your product.
Segmentation & targeting
Target specific users with segments. A segment defines criteria that users must match (based on custom attributes). All criteria must match for a user to qualify.
Criteria operators
Segment criteria support different operators depending on the attribute type:
| Type | Operators |
|---|---|
| String | equals, not_equals, contains, does_not_contain |
| Number | equals, not_equals, greater_than, greater_than_or_equal, less_than, less_than_or_equal |
| Datetime | equals, not_equals, more_than, less_than, more_than_days_ago, less_than_days_ago |
Example: Target enterprise users who signed up in the last 30 days — create a segment with plan equals "enterprise" and created_at less_than_days_ago 30.
Scheduling
Surveys can be activated manually or scheduled to start and stop automatically.
Manual activation
Create the survey as a draft, then activate it whenever you're ready. Deactivate it manually when you're done collecting responses.
Scheduled activation
Set a start date and optional end date. The survey activates automatically when the start date arrives and deactivates when the end date passes.
Configuration
Fine-tune survey behavior from Settings → Snippet Configuration.
| Setting | Default | Description |
|---|---|---|
| View frequency | 24 hours | Minimum time before showing the same survey again to a user who hasn't responded. |
| Survey buffer | 24 hours | If a user has seen any survey within this window, no additional surveys will be shown. Set to 0 to disable. |
| NPS frequency | 180 days | After responding to an NPS survey, the user won't see another NPS for this many days. |
| CSAT frequency | 30 days | After responding to a CSAT survey, the user won't see another CSAT for this many days. |
| Custom frequency | 90 days | After responding to a custom survey, the user won't see another custom survey for this many days. |
| NPS email follow-up | 14 days | For NPS surveys, send a follow-up email if the user hasn't responded within this window. |
URL blocklist
Prevent surveys from showing on specific pages. Add URL patterns in Settings → Snippet Configuration.
| Pattern | Matches |
|---|---|
| /admin/* | All pages under /admin/ |
| */checkout | Any URL ending in /checkout |
| *login* | Any URL containing "login" |
| /settings | Exact match for /settings |
API reference
The BetterFeedback snippet communicates with these API endpoints. Available on the Studio plan for direct integration.
Base URL: https://app.betterfeedback.io/api/v1/snippet
/identify
Link an anonymous BetterFeedback identity to your user. Called automatically by BetterFeedback.init().
Request body
{
"bf_identifier": "auto-generated-uuid",
"external_identifier": "your-user-id",
"custom_attributes": {
"email": "user@example.com",
"plan": "pro"
}
}
Response
{ "status": "success", "identity_id": 42 }
/active_surveys
Fetch active surveys eligible for the current user.
Query parameters
| key | Your public key (required) |
| bf_identifier | The user's BetterFeedback ID |
| attributes | JSON string of user attributes |
| current_url | Current page URL (for blocklist filtering) |
Response
{
"surveys": [
{
"id": 1,
"title": "How likely are you to recommend us?",
"description": "We'd love your feedback.",
"survey_type": "nps",
"follow_up_question": "What could we improve?",
"display_position": "centered"
}
]
}
/survey_responses
Submit a survey response.
Request body
{
"survey_id": 1,
"bf_identifier": "auto-generated-uuid",
"rating": 9,
"open_ended_response": "Love the simplicity!",
"custom_attributes": { "plan": "pro" }
}
Validation
| NPS | rating must be 0–10 |
| CSAT | rating must be 1–5 |
| Custom | Use answers object instead of rating |
Response
{ "status": "success", "response_id": 123 }
Need help?
Reach out at support@betterfeedback.com and we'll get back to you quickly.