Documentation

Everything you need to integrate Pollenate feedback widgets and APIs into your application.

🚀Quick Start

Get up and running with Pollenate in under 5 minutes. Collect your first piece of feedback today.

1. Add the widget script to your HTML
<script 
  src="https://pollenate.dev/widget.js"
  data-inbox-key="YOUR_INBOX_KEY"
  data-api-key="YOUR_API_KEY"
  data-type="emoji"
  async
></script>

That's it! The widget will automatically appear on your page. You'll need both an inbox key (from the Inboxes page) and an API key with the "collect" scope (from the API Keys page).

🔐Authentication

Pollenate uses two authentication methods depending on your use case:

API Keys (for widgets & integrations)

Use API keys for server-to-server integrations and widget authentication. Pass your key in the X-Pollenate-Key header.

curl -X POST https://api.pollenate.dev/collect \
  -H "X-Pollenate-Key: pk_live_xxx" \
  -H "Content-Type: application/json" \
  -d '{"type": "emoji", "score": 5, "comment": "Great!"}'

JWT Bearer Token (for dashboard API)

Use JWT tokens for authenticated user sessions. Tokens are obtained via OTP email verification.

curl https://api.pollenate.dev/organizations \
  -H "Authorization: Bearer eyJhbGc..."

📦Embed Widget

The Pollenate widget can be embedded in any website with a single script tag.

Script Attributes

AttributeRequiredDescription
data-inbox-keyYesYour inbox's public key (from the Inboxes page)
data-api-keyYesYour API key with "collect" scope (from the API Keys page)
data-typeNoWidget type: emoji, stars, thumbs, nps, csat, text
data-positionNoPosition: bottom-right, bottom-left, top-right, top-left
data-themeNoTheme: light, dark, or custom theme ID
data-promptNoCustom prompt text
data-inlineNoSet to "true" for inline widget (no floating button, form shows directly on page)
data-containerNoCSS selector for a container element to mount the widget into (e.g. "#feedback"). Implies inline mode.
data-contextNoJSON object with custom context metadata (e.g. '{"page":"pricing","userId":"123"}')
data-debugNoSet to "true" for console logging (default: false)
data-track-impressionsNoSet to "false" to disable page view / impression tracking (default: true)
data-strip-query-paramsNoSet to "true" to strip query parameters from tracked URLs for privacy (default: false). Only the domain and path are recorded.

🎨Widget Types

😞 😐 🙂 😄 🤩

Emoji

5-point emoji scale for quick sentiment

type="emoji"
⭐⭐⭐⭐⭐

Stars

Classic 5-star rating

type="stars"
👍 👎

Thumbs

Simple up/down voting

type="thumbs"
0─────10

NPS

Net Promoter Score (0-10)

type="nps"
1─────5

CSAT

Customer Satisfaction (1-5)

type="csat"
💬

Text

Open-ended text feedback

type="text"

🎭Customization

Customize the widget appearance using CSS variables or create custom themes in the dashboard.

CSS Variables
:root {
  --pollenate-primary: #f59e0b;
  --pollenate-primary-hover: #d97706;
  --pollenate-bg: #ffffff;
  --pollenate-text: #1e293b;
  --pollenate-border: #e2e8f0;
  --pollenate-radius: 12px;
}

⚛️React Package

For React apps, install @pollenate/react for a fully typed, native React component — no script tags or DOM manipulation needed.

Installation

Terminal
npm install @pollenate/react
# or
pnpm add @pollenate/react
# or
yarn add @pollenate/react

Quick Start

React Component
import { PollenateWidget } from '@pollenate/react';

export function App() {
  return (
    <PollenateWidget
      inboxKey="YOUR_INBOX_KEY"
      apiKey="YOUR_API_KEY"
      type="stars"
      theme="auto"
      onSubmit={(event) => {
        console.log('Feedback submitted:', event.detail);
      }}
    />
  );
}

Inline Widget

Add inline to render the widget directly in your page flow instead of as a floating button:

Inline Example
<PollenateWidget
  inboxKey="my-inbox"
  apiKey="pk_live_xxx"
  type="thumbs"
  inline
  prompt="Was this page helpful?"
/>

Custom Themed

Override colors, border radius, fonts, and dark-mode colors:

Themed Example
<PollenateWidget
  inboxKey="my-inbox"
  apiKey="pk_live_xxx"
  type="nps"
  theme="auto"
  primaryColor="#6366f1"
  borderRadius={12}
  buttonText="Submit Score"
  darkPrimaryColor="#818cf8"
  darkBgColor="#1e1b4b"
  hideBranding
/>

Props Reference

PropTypeDefaultDescription
inboxKeystringYour inbox key (required)
apiKeystringYour API key with collect scope (required)
typestringemojiemoji, stars, thumbs, nps, csat, or text
themestringlightlight, dark, or auto
inlinebooleanfalseRender inline instead of floating
positionstringbottom-rightFloating position (bottom-right, bottom-left, top-right, top-left)
promptstringCustom prompt text above the rating
contextobjectMetadata sent with each submission
primaryColorstringPrimary accent color (hex)
bgColorstringWidget background color (hex)
onSubmitfunctionCallback when feedback is submitted
onImpressionfunctionCallback on widget impression

📦 Full props list: See all available props including dark-mode overrides, animation, and branding options in the npm package README.

🛠️Custom Widgets

Want complete control over your feedback UI? Build your own custom widget using our REST API. This allows you to match your brand perfectly and integrate feedback into any user flow. If you're using React, consider the @pollenate/react package first — it handles all the API calls and UI for you.

💡 When to use custom widgets: Use the API directly when you need a fully custom UI, want to embed feedback in specific flows (like checkout), or integrate with frameworks we don't support yet.

Basic Example

Here's a complete example of a custom feedback form using vanilla HTML/JavaScript:

HTML + JavaScript
<form id="custom-feedback">
  <p>How would you rate your experience?</p>
  <div class="rating-buttons">
    <button type="button" data-score="1">😞</button>
    <button type="button" data-score="2">😐</button>
    <button type="button" data-score="3">🙂</button>
    <button type="button" data-score="4">😄</button>
    <button type="button" data-score="5">🤩</button>
  </div>
  <textarea name="comment" placeholder="Any additional feedback?"></textarea>
  <button type="submit">Submit</button>
</form>

<script>
let selectedScore = null;

document.querySelectorAll('[data-score]').forEach(btn => {
  btn.onclick = () => selectedScore = parseInt(btn.dataset.score);
});

document.getElementById('custom-feedback').onsubmit = async (e) => {
  e.preventDefault();
  
  const response = await fetch('https://api.pollenate.dev/collect', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'X-Pollenate-Key': 'YOUR_API_KEY'
    },
    body: JSON.stringify({
      inboxKey: 'YOUR_INBOX_KEY',
      type: 'emoji',
      score: selectedScore,
      comment: e.target.comment.value,
      context: {
        page: window.location.pathname,
        userAgent: navigator.userAgent
      }
    })
  });
  
  if (response.ok) {
    alert('Thank you for your feedback!');
  }
};
</script>

React Example (DIY)

This shows how to build a completely custom feedback UI from scratch using the API directly. For a drop-in solution, see the React Package section above.

Custom React Component
import { useState } from 'react';

export function CustomFeedback() {
  const [score, setScore] = useState(null);
  const [comment, setComment] = useState('');
  const [submitted, setSubmitted] = useState(false);

  const handleSubmit = async () => {
    const response = await fetch('https://api.pollenate.dev/collect', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'X-Pollenate-Key': process.env.POLLENATE_API_KEY
      },
      body: JSON.stringify({
        inboxKey: 'YOUR_INBOX_KEY',
        type: 'emoji',
        score,
        comment,
        context: { page: window.location.pathname }
      })
    });
    
    if (response.ok) setSubmitted(true);
  };

  if (submitted) return <p>Thanks for your feedback! 🎉</p>;

  return (
    <div className="feedback-widget">
      <p>How was your experience?</p>
      <div className="emojis">
        {['😞', '😐', '🙂', '😄', '🤩'].map((emoji, i) => (
          <button
            key={i}
            onClick={() => setScore(i + 1)}
            className={score === i + 1 ? 'selected' : ''}
          >
            {emoji}
          </button>
        ))}
      </div>
      <textarea
        value={comment}
        onChange={(e) => setComment(e.target.value)}
        placeholder="Tell us more..."
      />
      <button onClick={handleSubmit} disabled={!score}>
        Submit Feedback
      </button>
    </div>
  );
}

API Request Format

FieldTypeRequiredDescription
inboxKeystringYesYour inbox's public key
typestringYesemoji, stars, thumbs, nps, csat, or text
scorenumberNo*0-10 for NPS, 1-5 for others, 0/1 for thumbs
commentstringNo*Text feedback (max 2000 chars)
contextobjectNoCustom metadata (page URL, user ID, etc.)

* At least one of score or comment is required

Score Ranges by Type

emoji

Score 1-5 (😞 to 🤩)

stars

Score 1-5 (⭐ to ⭐⭐⭐⭐⭐)

thumbs

Score 0 (👎) or 1 (👍)

nps

Score 0-10

csat

Score 1-5

text

No score, comment only

Using Context for Insights

The context field lets you attach metadata to each feedback submission. This enables powerful filtering and analysis in your dashboard.

// Example context object
{
  "context": {
    "page": "/checkout",
    "userId": "user_abc123",
    "plan": "pro",
    "feature": "dark-mode",
    "experiment": "new-pricing-v2",
    "sessionId": "sess_xyz789"
  }
}

📋Feedback Pages

Feedback Pages are standalone, branded feedback forms that you create through the Pollenate dashboard. Unlike widgets (which embed into existing pages), Feedback Pages are hosted at their own URL and can collect multi-question surveys from users.

💡 When to use Feedback Pages vs. Widgets: Use widgets when you want to collect quick, single-question feedback inline on your existing website. Use Feedback Pages when you need a multi-question form, want to share via QR code or printed materials, or need a standalone survey that doesn't require embedding on an existing site.

Key Features

🛠️ Visual Form Builder

Drag-and-drop editor with 7+ question types. Add, edit, delete, and reorder questions with a live preview.

🎨 Custom Branding

Match your brand with custom accent colors, background colors, and brand association. Configurable thank-you messages.

📱 Multiple Sharing Options

Share via direct link, QR code (PNG/SVG), email signature button, embeddable iframe, or print-ready flyer.

📊 Built-in Analytics

View response counts, page views, conversion rates, daily trends, and per-question breakdowns with score distributions.

🔨Form Builder

The form builder lets you create multi-question feedback forms using a visual editor. Each question has a type, prompt, optional description, and can be marked as required.

Supported Question Types

TypeAPI ValueScore RangeDescription
⭐ Star Ratingstar_rating1–5Classic 5-star rating
😄 Emojiemoji1–55-point emoji sentiment scale
👍 Thumbsthumbs0–1Simple thumbs up/down
📊 NPSnps0–10Net Promoter Score
💬 TexttextOpen-ended text response
🔘 Single Choicesingle_choiceSelect one option from a list
☑️ Multiple Choicemulti_choiceSelect multiple options from a list

Page Settings

SettingDescription
Title & DescriptionShown at the top of the public feedback page
URL SlugCustom URL path (e.g. /f/your-org/my-survey)
StatusDraft (private), Published (live), or Archived (closed)
Accent & Background ColorCustomize the page's accent and background colors to match your brand
Thank You MessageCustom message shown after submission, with optional redirect URL
Require Contact InfoAsk respondents for name and email before submitting
Allow AnonymousLet respondents skip contact info even if the field is shown
Single SubmissionLimit to one response per browser using local storage

🔗Sharing & Embedding

Once your Feedback Page is published, you have multiple ways to share it with respondents.

🔗 Direct Link

Share the URL directly via email, messaging apps, or social media.

https://pollenate.dev/f/your-org/your-page-slug

📱 QR Code

Generate QR codes in PNG or SVG format at multiple sizes (128px to 1024px). Perfect for flyers, posters, table tents, and business cards.

GET https://api.pollenate.dev/qr?data=YOUR_PAGE_URL&size=256&format=png&margin=4

Parameters:
  data    - URL to encode (required)
  size    - Image size in pixels: 128, 256, 512, 1024 (default: 256)
  format  - Output format: png or svg (default: png)
  margin  - Quiet zone margin in modules (default: 4)

📧 Email Signature Button

Copy an HTML snippet that renders a branded button in your email signature. The button uses your page's accent color.

<table cellpadding="0" cellspacing="0" border="0">
  <tr>
    <td style="padding: 10px 0;">
      <a href="https://pollenate.dev/f/your-org/your-page"
         style="display: inline-block; padding: 8px 16px;
                background-color: #f59e0b; color: #ffffff;
                text-decoration: none; border-radius: 6px;
                font-family: Arial, sans-serif; font-size: 14px;">
        Share Your Feedback
      </a>
    </td>
  </tr>
</table>

🖥️ Embed on Website

Embed the full feedback page on your website using an iframe. Add ?embed=true to remove the header and footer.

<iframe
  src="https://pollenate.dev/f/your-org/your-page?embed=true"
  width="100%"
  height="600"
  frameborder="0"
  style="border: none; border-radius: 12px;"
  title="Feedback Form"
></iframe>

🖨️ Print Flyer

Generate a ready-to-print flyer with your page title, description, QR code, and a call-to-action. Uses the Print dialog for easy printing on any device. Great for clinics, restaurants, offices, and events.

⚙️Pages API

Manage Feedback Pages programmatically via the REST API. All endpoints require JWT Bearer token authentication.

GET/organizations/:orgId/feedback-pages

List all feedback pages. Supports filtering by status and brandId.

POST/organizations/:orgId/feedback-pages

Create a new feedback page with title, description, slug, status, and settings.

GET/organizations/:orgId/feedback-pages/:pageId

Get a feedback page with its questions and submission count.

PUT/organizations/:orgId/feedback-pages/:pageId

Update page settings (title, description, status, colors, submission settings, etc.).

POST/organizations/:orgId/feedback-pages/:pageId/questions

Add a question to the page.

GET/organizations/:orgId/feedback-pages/:pageId/stats

Get analytics: total responses, page views, conversion rate, daily trends, and per-question breakdowns.

GET/f/:orgSlug/:pageSlug

Public-facing feedback page (no auth required). Append ?embed=true for iframe mode.

Submit Responses (Public)

POST/f/:orgSlug/:pageSlug/submit

Submit responses to a published feedback page. Protected by Cloudflare Turnstile.

{
  "answers": {
    "question-id-1": { "score": 5 },
    "question-id-2": { "textValue": "Great experience!" },
    "question-id-3": { "multiValues": ["Search", "Referral"] }
  },
  "respondentName": "Jane Doe",
  "respondentEmail": "[email protected]",
  "turnstileToken": "CAPTCHA_TOKEN"
}

API Overview

The Pollenate API is a RESTful API that uses JSON for request and response bodies.

Base URLs
PRODhttps://api.pollenate.dev
DEVhttp://localhost:8787

For the complete API specification, see our OpenAPI 3.1 spec.

📥Feedback Collection

POST/collect

Submit feedback to an inbox. Requires API key authentication.

Request Body

{
  "type": "emoji",        // emoji, stars, thumbs, nps, csat, text
  "score": 5,             // 0-10 for nps, 1-5 for others
  "comment": "Loving it!",// Optional text feedback
  "context": {            // Optional metadata
    "page": "/checkout",
    "userId": "user_123"
  }
}

Response

{
  "id": "fb_abc123",
  "createdAt": "2026-02-04T12:00:00Z"
}

📬Inboxes

Inboxes are containers for feedback. Each inbox has a unique key used to submit feedback.

GET/organizations/:orgId/inboxes

List all inboxes in an organization.

POST/organizations/:orgId/inboxes

Create a new inbox.

GET/organizations/:orgId/inboxes/:inboxId/feedback

Get all feedback for an inbox with pagination and filters.

🤖AI Agent Integration

AI agents can submit feedback during conversations with users — capturing satisfaction, sentiment, and product feedback in real-time without interrupting the flow.

How it works

When a user expresses satisfaction or frustration during a conversation, the AI agent can submit structured feedback to Pollenate using the same /collect endpoint used by widgets. The feedback appears in your dashboard alongside widget submissions.

User talks to AIAgent detects sentimentPOST /collectDashboard

Skill File Discovery

Pollenate publishes a skill.md file that AI agents and platforms can use to discover and learn the API — similar to how MCP servers expose capabilities.

# Install the skill locally for your AI agent
mkdir -p ~/.agent/skills/pollenate
curl -s https://pollenate.dev/skill.md > ~/.agent/skills/pollenate/SKILL.md
curl -s https://pollenate.dev/skill.json > ~/.agent/skills/pollenate/skill.json

Agent Examples

After resolving a support issue

curl -X POST https://api.pollenate.dev/collect \
  -H "Content-Type: application/json" \
  -H "X-Pollenate-Key: YOUR_API_KEY" \
  -d '{
    "inboxKey": "support-chat",
    "type": "thumbs",
    "score": 1,
    "comment": "User confirmed their issue was resolved",
    "context": {
      "source": "ai-agent",
      "agentName": "SupportBot",
      "topic": "password-reset"
    }
  }'

Capturing conversation sentiment

curl -X POST https://api.pollenate.dev/collect \
  -H "Content-Type: application/json" \
  -H "X-Pollenate-Key: YOUR_API_KEY" \
  -d '{
    "inboxKey": "sentiment-tracker",
    "type": "emoji",
    "score": 4,
    "context": {
      "source": "ai-agent",
      "detectedSentiment": "positive",
      "conversationTurns": 8,
      "agentModel": "claude-sonnet-4"
    }
  }'

Logging product feedback from conversation

curl -X POST https://api.pollenate.dev/collect \
  -H "Content-Type: application/json" \
  -H "X-Pollenate-Key: YOUR_API_KEY" \
  -d '{
    "inboxKey": "product-feedback",
    "type": "text",
    "comment": "User requested dark mode support — 3rd request this week",
    "context": {
      "source": "ai-agent",
      "category": "feature-request",
      "priority": "high"
    }
  }'

Best Practices

  • Ask first — Always confirm with the user before submitting feedback on their behalf.
  • Use context — Include source: "ai-agent" in the context so teams can filter agent-submitted feedback.
  • Group with sessionId — Use the same sessionId for all feedback from one conversation.
  • Pick the right type — Use thumbs for quick yes/no, text for qualitative feedback, nps for loyalty scores.
  • Handle rate limits — If you receive a 429 response, wait for the retryAfter duration before retrying.

Developer FAQ

Common questions about integrating and using the Pollenate API and widgets.

Do I need a build step to use the widget?
No. The Pollenate widget is a standalone script you add via a <script> tag. It works on any website — static HTML, WordPress, React, Next.js, or any other framework — with zero build configuration.
What is an inbox key vs. an API key?
An inbox key identifies which inbox receives the feedback. An API key authenticates the request. You need both: the inbox key (from the Inboxes page) tells Pollenate where to route the feedback, and the API key (from the API Keys page with the "collect" scope) authorizes the submission.
How do I authenticate API requests?
For widget and server-to-server integrations, pass your API key in the X-Pollenate-Key header. For dashboard API access, use a JWT Bearer token obtained via OTP email verification in the Authorization header.
Can I use Pollenate with React?
Yes! Install @pollenate/react (npm install @pollenate/react) for a fully typed, drop-in React component. See the React Package section in the docs above. You can also use the vanilla script tag widget directly in any React app.
What widget types are available?
Pollenate supports six widget types: thumbs (up/down), stars (1–5 rating), NPS (0–10 scale), CSAT (1–5 satisfaction), emoji (sentiment reactions), and text (open-ended comments). Set the type via the data-type attribute or the type configuration option.
How does the semantic search API work?
POST a natural language query to /organizations/:orgId/search. Pollenate generates an AI embedding of your query and performs vector similarity search against all stored feedback, returning the most semantically relevant results. You can filter by inbox, score range, and more.
Is there a rate limit on the collect endpoint?
The Starter plan allows up to 5,000 events per month. Team plans support 100,000 events per month. Enterprise plans have no hard limits. All plans include burst protection to prevent abuse.
Can I listen for widget events in my app?
Yes. The widget emits a "pollenate:submit" CustomEvent on the window object whenever feedback is submitted. Listen for it with window.addEventListener("pollenate:submit", callback) to integrate with your analytics or trigger custom behavior.
How are Feedback Pages different from widgets?
Widgets are lightweight embeds you drop into existing pages for quick, single-question feedback. Feedback Pages are standalone, multi-question forms hosted at their own URL. Use Feedback Pages when you need multi-question surveys, want to share via QR code or print, or need a branded form that stands on its own without embedding into an existing site.
Can I embed a Feedback Page on my website?
Yes! Each published Feedback Page can be embedded using an iframe. Append ?embed=true to the URL to remove headers and footers for a clean embed. You can also share Feedback Pages via direct link, QR code, email signature button, or a print-ready flyer.

Ready to start collecting feedback?

Create your free account and have your first widget live in minutes.

How's your experience?

🎉

Thank you for your feedback!

Powered by Pollenate