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)

🎨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;
}

🛠️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.

💡 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

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"
  }
}

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.

Ready to start collecting feedback?

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