---
title: "Documentation | FeatureBot"
url: https://featurebot.com/documentation
description: "Learn how to integrate FeatureBot into your product with our comprehensive documentation for widget installation, webhooks, and API usage."
---

# Documentation

Everything you need to integrate FeatureBot into your product. From widget installation to webhooks and the JavaScript API.

[

### Widget Installation

](#widget)[

### Custom Styling

](#styling)[

### Webhooks

](#webhooks)[

### JavaScript API

](#api)

## Widget Installation

### Basic Installation

Add this snippet before the closing `</body>` tag on every page where you want the widget to appear.

<script
  async
  src="https://cdn.featurebot.com/widget.js"
  data-key="YOUR\_PUBLIC\_KEY"
></script>

Replace `YOUR_PUBLIC_KEY` with your workspace public key from Settings → Install.

### With User Context

Pass user information to enable personalization, MRR tracking, and segment-based analytics.

<script
  async
  src="https://cdn.featurebot.com/widget.js"
  data-key="YOUR\_PUBLIC\_KEY"
  data-user-id="USER\_ID"
  data-email="USER\_EMAIL"
  data-name="USER\_NAME"
  data-plan="PLAN\_NAME"
  data-mrr="MRR\_IN\_CENTS"
  data-company="COMPANY\_NAME"
  data-role="USER\_ROLE"
  data-company-size="COMPANY\_SIZE"
  data-attributes='{"key": "value"}'
></script>

#### Available Attributes:

-   `data-user-id` - Your internal user ID
-   `data-email` - User's email address
-   `data-name` - User's display name
-   `data-plan` - Subscription plan name (e.g., "Pro", "Enterprise")
-   `data-mrr` - Monthly recurring revenue in cents
-   `data-company` - Company or organization name
-   `data-role` - User's role in the company (e.g., "Admin", "Developer")
-   `data-company-size` - Company size or headcount (e.g., "10-50", "Enterprise")
-   `data-attributes` - JSON string of custom key-value pairs

### Single Page Applications

For React, Vue, Angular, or other SPAs where the user logs in after page load, use the JavaScript API to identify users dynamically.

// After user logs in
window.FeatureBot.identify({
  userId: user.id,
  email: user.email,
  name: user.name,
  plan: user.subscription.plan,
  mrr: user.subscription.mrr,
  company: user.company.name,
  role: user.role,
  companySize: user.company.size,
  attributes: {
    team: user.team,
    signupSource: user.signupSource,
    betaFeatures: user.betaFeatures
  }
});

// When user logs out
window.FeatureBot.reset();

## Custom Styling

### CSS Variables API

Customize the widget appearance using CSS variables. Pass them via the `data-css-vars` attribute or dynamically with `FeatureBot.setTheme()`.

<script
  async
  src="https://cdn.featurebot.com/widget.js"
  data-key="YOUR\_PUBLIC\_KEY"
  data-css-vars='{
    "--fb-primary-color": "#0066cc",
    "--fb-user-message-bg": "#0066cc",
    "--fb-input-bg": "#f0f0f0"
  }'
></script>

### Available Variables

Trigger Button

-   `--fb-button-bg` - Button background color
-   `--fb-button-text` - Button text color
-   `--fb-button-border` - Button border style (none, thin, thick)
-   `--fb-button-border-color` - Button border color
-   `--fb-button-emoji` - Button icon/emoji (e.g., "💬", "🚀", or empty string)

Chat Container

-   `--fb-chat-border-radius` - Chat window corner radius (e.g., "0", "12px", "24px")
-   `--fb-shadow` - Chat window box shadow

Chat Interior

-   `--fb-primary-color` - Accent color for header, buttons, focus states
-   `--fb-chat-bg` - Chat window background
-   `--fb-text-color` - Primary text color
-   `--fb-muted-text` - Secondary/muted text color
-   `--fb-input-bg` - Input field background
-   `--fb-input-border` - Input field border color
-   `--fb-input-text` - Input field text color
-   `--fb-user-message-bg` - User message bubble background
-   `--fb-user-message-text` - User message text color
-   `--fb-bot-message-bg` - Bot message bubble background
-   `--fb-bot-message-text` - Bot message text color

### Note on Fonts

Only preset fonts are available: Inter, Poppins, Roboto, Open Sans, Lato, and System UI. Configure fonts in your dashboard under Widget Settings. Need a different font? Request it via the FeatureBot feedback button in your dashboard.

## Webhooks

### Overview

Webhooks allow you to receive real-time notifications when events occur in FeatureBot. Configure webhook endpoints in Settings → Webhooks.

### Available Events

`feedback.created`

Triggered when new feedback is submitted via the widget, API, or public board.

`voice.added`

Triggered when a user adds their voice to existing feedback (me too!).

`feedback.status_changed`

Triggered when feedback status changes (e.g., Open → In Progress → Completed).

`feedback.clustered`

Triggered when feedback is grouped into a cluster by AI or manually.

### Example Payload

Here's an example payload for the `feedback.created` event:

{
  "event": "feedback.created",
  "timestamp": "2024-01-15T10:30:00.000Z",
  "feedback": {
    "id": "fb\_abc123",
    "title": "Add dark mode support",
    "description": "It would be great to have a dark mode option",
    "category": "FEATURE\_REQUEST",
    "status": "OPEN",
    "priority": "MEDIUM",
    "voiceCount": 1,
    "totalMrr": 9900,
    "avgSentiment": 0.8,
    "aiSummary": null,
    "aiTags": \["ui", "accessibility"\],
    "createdAt": "2024-01-15T10:30:00.000Z",
    "updatedAt": "2024-01-15T10:30:00.000Z"
  },
  "workspace": {
    "id": "ws\_xyz789",
    "name": "Acme Corp",
    "slug": "acme-corp"
  },
  "triggeredBy": "widget"
}

### Request Headers

Each webhook request includes the following headers:

`X-Webhook-Signature`

HMAC-SHA256 signature for verification

`X-Webhook-Event`

The event type (e.g., FEEDBACK\_CREATED)

`X-Webhook-Delivery-Id`

Unique ID for this delivery attempt

`Content-Type`

application/json

### Verifying Signatures

Always verify webhook signatures to ensure requests are from FeatureBot. The signature format is: `t=timestamp,v1=signature`

import crypto from 'crypto';

function verifyWebhookSignature(
  payload: string,
  signature: string,
  secret: string
): boolean {
  // Parse signature: t=<timestamp>,v1=<signature>
  const parts = signature.split(',');
  const timestamp = parts.find(p => p.startsWith('t='))?.slice(2);
  const sig = parts.find(p => p.startsWith('v1='))?.slice(3);

  if (!timestamp || !sig) return false;

  // Check timestamp (within 5 minutes)
  const now = Math.floor(Date.now() / 1000);
  if (Math.abs(now - parseInt(timestamp)) > 300) return false;

  // Verify signature
  const signedPayload = \`${timestamp}.${payload}\`;
  const expectedSig = crypto
    .createHmac('sha256', secret)
    .update(signedPayload)
    .digest('hex');

  return crypto.timingSafeEqual(
    Buffer.from(sig),
    Buffer.from(expectedSig)
  );
}

// In your webhook handler
app.post('/webhooks/featurebot', (req, res) => {
  const signature = req.headers\['x-webhook-signature'\];
  const isValid = verifyWebhookSignature(
    JSON.stringify(req.body),
    signature,
    process.env.FEATUREBOT\_WEBHOOK\_SECRET
  );

  if (!isValid) {
    return res.status(401).json({ error: 'Invalid signature' });
  }

  // Process the webhook...
  res.status(200).json({ received: true });
});

### Delivery & Retries

-   • Webhooks timeout after **30 seconds** by default
-   • Failed deliveries are retried up to **3 times**
-   • Retries use exponential backoff
-   • Return a **2xx status code** to acknowledge receipt
-   • View delivery history in Settings → Webhooks

## JavaScript API

Control the widget programmatically using the global `window.FeatureBot` object.

`window.FeatureBot.open()`

Open the feedback widget

`window.FeatureBot.open({ prefill: "I want..." })`

Open with pre-filled text

`window.FeatureBot.close()`

Close the widget

`window.FeatureBot.isOpen()`

Returns true if the widget is currently open

`window.FeatureBot.identify({ userId, email, name, plan, mrr, company, role, companySize, attributes })`

Identify the current user (for SPAs). All fields are optional. The `attributes` field accepts any JSON object for custom data.

`window.FeatureBot.reset()`

Clear user identity (on logout)

`window.FeatureBot.setTheme({ cssVars })`

Customize widget colors dynamically using CSS variables. Changes apply immediately if the widget is open.

// Customize widget colors dynamically
window.FeatureBot.setTheme({
  '--fb-primary-color': '#0066cc',
  '--fb-chat-bg': '#fafafa',
  '--fb-user-message-bg': '#0066cc',
  '--fb-bot-message-bg': '#e5e5e5'
});

`window.FeatureBot.hide()`

Hide the widget completely (button and chat window)

`window.FeatureBot.show()`

Show the widget again after hiding

## Ready to Get Started?

Create your free account and start collecting feedback in minutes.

[Get Started Free](/signup)