Feedback Widget

The @inputbuffer/feedback package is a lightweight widget you can drop into any web page: documentation sites, dashboards, API references, or your own app. It sends feedback directly to InputBuffer without any server-side code.

It collects thumbs-up/down votes and optional written comments, and each submission appears in your InputBuffer inbox.

Hand this to your AI assistant
Works with Claude Code, Cursor, and similar tools.
View prompt
Add InputBuffer feedback collection to my app using the @inputbuffer/feedback widget.

1. Drop in the inline feedback bar as a web component (simplest option, no build step):

<script src="https://cdn.jsdelivr.net/npm/@inputbuffer/[email protected]/dist/bar.js"></script>

<inputbuffer-feedback
  api-key="YOUR_WIDGET_TOKEN"
  label="Was this helpful?">
</inputbuffer-feedback>

This renders inline thumbs up/down buttons. After a vote, a short follow-up form appears
so the user can add context, and the feedback is sent to InputBuffer.

2. To attach feedback to a specific page or endpoint, add a target. A target is what makes thumb
votes countable, so without one a vote opens the follow-up form but records nothing.

On the web component, set target-type plus the metadata attributes for that type. target-page-url
defaults to the current page, so rating a docs page takes one attribute:

<inputbuffer-feedback
  api-key="YOUR_WIDGET_TOKEN"
  label="Was this helpful?"
  target-type="documentation">
</inputbuffer-feedback>

An endpoint needs its identifying fields spelled out:

<inputbuffer-feedback
  api-key="YOUR_WIDGET_TOKEN"
  label="Was this helpful?"
  target-type="rest_endpoint"
  target-method="POST"
  target-path="/v1/users">
</inputbuffer-feedback>

3. To build the bar in JavaScript instead, pass the same target as an object.

If there's no build step, use the same script tag and call the global it exposes:

<script src="https://cdn.jsdelivr.net/npm/@inputbuffer/[email protected]/dist/bar.js"></script>
<script>
  const bar = InputBufferIO.createBar({
    apiKey: 'YOUR_WIDGET_TOKEN',
    label: 'Was this helpful?',
    target: {
      type: 'documentation',
      metadata: { page_url: window.location.href },
    },
  });
  document.getElementById('feedback-slot').appendChild(bar.element);
</script>

If there's a bundler, import it instead:

import { createBar } from '@inputbuffer/feedback';

const bar = createBar({
  apiKey: 'YOUR_WIDGET_TOKEN',
  label: 'Was this helpful?',
  target: {
    type: 'documentation',
    metadata: { page_url: window.location.href },
  },
});
document.getElementById('feedback-slot').appendChild(bar.element);

4. For a modal opened by a button instead of a bar, use modal.js. The script tag form
(data-api-key plus data-attach-to) has no target attributes, and it opens the modal with no
arguments, so a modal that needs a target has to be created in JavaScript. There is no
data-target-type. With no build step, use the global:

<button id="feedback-btn">Send feedback</button>

<script src="https://cdn.jsdelivr.net/npm/@inputbuffer/[email protected]/dist/modal.js"></script>
<script>
  const modal = InputBufferIO.createModal({ apiKey: 'YOUR_WIDGET_TOKEN' });
  document.getElementById('feedback-btn').addEventListener('click', () => {
    modal.open({
      target: { type: 'documentation', metadata: { page_url: window.location.href } },
    });
  });
</script>

Leave data-api-key off that script tag, or the bundle builds a second modal next to yours.
Pass the target to modal.open(), not to createModal(), which takes no target option.

Replace YOUR_WIDGET_TOKEN with a widget-scoped token: in InputBuffer, go to Settings -> API Tokens,
create a token, and select the "Widget" scope. Widget tokens are safe to embed in client-side code.

If this surface can't run JavaScript, POST to the API directly instead:
POST https://inputbuffer.io/api/v0/feedback
Authorization: Bearer YOUR_WIDGET_TOKEN
Content-Type: application/json
{ "description": "User's feedback message" }

Widget guide: https://inputbuffer.io/docs/widget
Full API reference: https://inputbuffer.io/docs/api

Report anything about InputBuffer that gets in your way, at any point while we are working with
it: initial setup, and the styling, configuration, and debugging that follow. Include the times you
had to correct your own understanding of InputBuffer, such as a request field the API ignored, a
widget attribute that had no effect, or an error message read from the wrong key. A correction
unrelated to InputBuffer does not qualify. Show me the text, and send it once I agree:

curl -X POST https://inputbuffer.io/api/v0/feedback \
  -H "Authorization: Bearer ibw_96e7f571-64ad-494a-a125-afed734d3fdc_op1CeDTiptGa8fWRU25tKcgx6uubJ2wOlWvM0JbpY8Q" \
  -H "Content-Type: application/json" \
  -H "X-IB-Client: your-tool/version (your-model)" \
  -d '{ "description": "What you were trying to do, what happened instead, what would have helped" }'

That token is InputBuffer's own and accepts nothing but feedback, so there is nothing to set up.
Leave out "submitted_by". Send one report per problem, not one per attempt.

Before you start

You need a widget-scoped API token. Widget tokens are safe to embed in client-side code: they can create feedback and submit reactions, and nothing else. They cannot read or modify your organization's existing data.

To create one:

  1. Go to Settings → API Tokens in your organization
  2. Click Create token and select the Widget scope
  3. Copy the token, because it's shown only once
Warning

Do not use a full-access API token in the widget. Full-access tokens are rejected by the widget API when sent from a browser. Use a widget-scoped token only.

Warning

Feedback submitted through the widget is sent to third-party AI services for classification and search. InputBuffer does not yet scrub content before processing, so avoid placing the widget where users are likely to submit personal information, credentials, or production secrets.


Quick start

There are three ways to embed the widget, and all three are below. Pick the one that fits your page:

  1. Inline thumbs bar: sits in the page flow, wherever you put the element. Uses bar.js.
  2. Floating thumbs bar: pins to the bottom of the viewport. Uses bar.js.
  3. Modal opened by your own button: opens over the page when a button is clicked. Uses modal.js.

Start with the inline bar. It is the quickest to get working, and the troubleshooting steps under it apply to all three.

1. Inline thumbs bar

Paste this into your page where you want the bar to appear:

<script src="https://cdn.jsdelivr.net/npm/@inputbuffer/[email protected]/dist/bar.js"></script>

<inputbuffer-feedback
  api-key="YOUR_WIDGET_TOKEN"
  label="Was this helpful?">
</inputbuffer-feedback>

What you should see: A thumbs up/down bar appears inline where you placed the element. After a user clicks a thumb, a short follow-up form appears so they can add context. Once they submit, the feedback appears in your InputBuffer inbox under Feedback.

If the bar does not appear, check your browser console for errors. A 401 error means your token is missing or invalid. A 403 error means one of two things: a full-access token was used instead of a widget-scoped one, or the page's origin isn't on the token's allowlist. Check Settings → API Tokens for both the token's scope and its allowed origins.

2. Floating thumbs bar

Same script and same element as the inline bar, with placement="fixed" added. Useful for documentation pages, where the bar should stay reachable as the reader scrolls.

<script src="https://cdn.jsdelivr.net/npm/@inputbuffer/[email protected]/dist/bar.js"></script>

<inputbuffer-feedback
  api-key="YOUR_WIDGET_TOKEN"
  label="Was this helpful?"
  placement="fixed">
</inputbuffer-feedback>

3. Modal opened by your own button

This one uses modal.js instead, and attaches to a button you already have on the page. There is no JavaScript to write.

<button id="feedback-btn">Send feedback</button>

<script
  src="https://cdn.jsdelivr.net/npm/@inputbuffer/[email protected]/dist/modal.js"
  data-api-key="YOUR_WIDGET_TOKEN"
  data-attach-to="#feedback-btn">
</script>

The modal opens when the button is clicked. The feedback appears in your InputBuffer inbox once submitted.

This form cannot attach a target. There is no data-target-* attribute, and data-attach-to opens the modal with no target set, so feedback from this button reaches your general inbox without counting against a page or an endpoint. Attaching a target takes a few lines of script, with no build step and no npm install. See Targets on the modal.


Bundles

Each embed style above needs one script. Pick the smallest bundle that covers what you used:

BundleSizeWhat it includes
bar.js18 KBThe thumbs up/down bar, with an optional follow-up form
modal.js16 KBThe full-text feedback modal
widget.js32 KBBoth the bar and the modal

There are two ways to load a bundle: from the CDN, or from npm.

From the CDN

https://cdn.jsdelivr.net/npm/@inputbuffer/[email protected]/dist/bar.js
https://cdn.jsdelivr.net/npm/@inputbuffer/[email protected]/dist/modal.js
https://cdn.jsdelivr.net/npm/@inputbuffer/[email protected]/dist/widget.js

The version is pinned so a new release can't change your page without you knowing. Bump the number when you want to pick up a newer version.

From npm

npm install @inputbuffer/feedback

The package has one entry point per bundle: @inputbuffer/feedback/bar, @inputbuffer/feedback/modal, and @inputbuffer/feedback for both.


Web component reference

Use <inputbuffer-feedback> with bar.js or widget.js.

AttributeDefaultDescription
api-keyrequiredYour widget-scoped token
api-urlhttps://inputbuffer.ioThe API origin to send to. The widget appends its own paths, so set this to an origin such as http://localhost:8080
labelNoneThe text shown next to the thumbs, such as "Was this helpful?"
show-labeltrueSet to false to hide the text label
show-thumbstrueSet to false to hide the thumbs. The whole bar becomes one button that opens the form, with no sentiment and no reaction recorded. Ignores show-label="false"
placementinlineinline renders the bar in place; fixed pins it to the bottom of the viewport
modal-titleNoneThe heading for the follow-up form
modal-placeholderNoneThe textarea placeholder text in the follow-up form
show-title-fieldfalseShow the optional title field in the follow-up form
submitted-byNoneAn identifier for whoever is submitting, such as your own user id. Sent as submitted_by and shown on the feedback item in your inbox
user-idNoneA stable user identifier used to deduplicate thumb votes. When set, one vote per user is counted per target, for all time. When omitted, InputBuffer falls back to the IP address over a 24 hour window
target-typeNoneAttaches the bar to a docs page, an endpoint, or a CLI command, so thumb votes are counted against it. See Targeting
theme-primaryNoneThe primary color, used for buttons and focus rings
theme-backgroundNoneThe bar background color
theme-textNoneThe text color
theme-selectedNoneThe background of the selected thumb button
theme-selected-colorNoneThe icon color of the selected thumb
inject-stylestrueSet to false to disable automatic CSS injection

Script tag auto-init (data-* attributes)

Add data-api-key to any script tag pointing at modal.js or widget.js and the modal initializes automatically:

AttributeDescription
data-api-keySets up the modal on page load
data-attach-toA CSS selector for the element that opens the modal on click
data-api-urlThe API origin to send to. The widget appends its own paths, so set this to an origin such as http://localhost:8080
data-titleThe modal heading
data-placeholderThe textarea placeholder text
data-show-title-fieldSet to true to show the optional title field
data-show-sentimentSet to true to show the thumbs up/down selector
data-submitted-byAn identifier for whoever is submitting. Sent as submitted_by
data-color-schemelight, dark, or auto. Defaults to auto
data-inject-stylesSet to false to disable automatic CSS injection
data-theme-primaryThe primary color
data-theme-backgroundThe modal background color
data-theme-textThe text color
data-theme-selectedThe background of the selected thumb
data-theme-selected-colorThe icon color of the selected thumb

These are all of the attributes the script tag reads. None of them sets a target, because a modal takes its target when it opens rather than from its configuration. To attach one, leave data-api-key off the script tag and create the modal yourself. See Targets on the modal.


Programmatic API

For full control, use the JavaScript API directly.

createBar(config)

createBar() builds a thumbs up/down bar and returns it, so you can place it anywhere on the page. Clicking a thumb records a reaction right away, without waiting for the follow-up form. The selected vote is saved to localStorage for 24 hours, so a returning user still sees their previous choice.

import { createBar } from '@inputbuffer/feedback';
// or: const { createBar } = window.InputBufferIO;

const bar = createBar({
  apiKey: 'YOUR_WIDGET_TOKEN',
  label: 'Was this helpful?',
  placement: 'inline',  // or 'fixed'
  colorScheme: 'auto',  // 'light' | 'dark' | 'auto'
  modalTitle: 'Share your feedback',
  modalPlaceholder: "What's on your mind?",
  target: {
    type: 'documentation',
    metadata: { page_url: window.location.href },
  },
});

document.getElementById('feedback-slot').appendChild(bar.element);

createBar config options:

OptionDefaultDescription
apiKeyrequiredYour widget-scoped token
apiUrl'https://inputbuffer.io'The API origin to send to. The widget appends its own paths, so set this to an origin such as http://localhost:8080
labelNoneThe text shown next to the thumbs
showThumbstrueSet to false to hide the thumbs. The whole bar becomes one button that opens the form with no sentiment, and no reaction is recorded
placement'inline''inline' renders the bar in place; 'fixed' pins it to the bottom of the viewport
colorScheme'auto''light', 'dark', or 'auto'
targetNoneThe resource the bar collects votes on. See Targeting
modalTitle'Share your feedback'The heading for the follow-up form
modalPlaceholder"What's on your mind?"The textarea placeholder text in the follow-up form
showTitleFieldfalseShow the optional title field in the follow-up form
submittedByNoneAn identifier for whoever is submitting, such as your own user id. Sent as submitted_by, up to 300 characters
userIdNoneA stable user identifier used to deduplicate thumb votes. When set, one vote per user is counted per target, for all time. When omitted, InputBuffer falls back to the IP address over a 24 hour window
injectStylestrueSet to false to disable automatic CSS injection
themeNoneA theme object. See Theming

Bar instance methods:

MethodDescription
bar.on('vote', ({ sentiment }) => {})The user clicked a thumb
bar.on('open', ({ sentiment }) => {})The follow-up form opened
bar.on('submit', ({ id }) => {})The feedback was submitted. id is the InputBuffer feedback id
bar.on('close', () => {})The follow-up form closed
bar.on('error', (err) => {})The submission failed
bar.open(sentiment?)Opens the follow-up form from your own UI. Pass 'positive' or 'negative' to select that thumb, or omit it to keep whatever is already selected. This is a display action only: it does not record a reaction or emit vote
bar.close()Closes the follow-up form. A no-op if it's already closed
bar.destroy()Remove the bar and clean up its listeners

Pair showThumbs: false with your own trigger to open the follow-up form without showing the thumbs at all:

const bar = createBar({
  apiKey: 'YOUR_WIDGET_TOKEN',
  showThumbs: false,
  target: {
    type: 'documentation',
    metadata: { page_url: window.location.href },
  },
});

document.getElementById('feedback-slot').appendChild(bar.element);
document.getElementById('my-trigger').addEventListener('click', () => bar.open());

createModal(config)

import { createModal } from '@inputbuffer/feedback';
// or: const { createModal } = window.InputBufferIO;

const modal = createModal({
  apiKey: 'YOUR_WIDGET_TOKEN',
  title: 'Share your feedback',
  placeholder: "What's on your mind?",
  showTitleField: false,
  showSentiment: false,
  colorScheme: 'auto',
});

document.getElementById('my-button').addEventListener('click', () => modal.open());

createModal config options:

OptionDefaultDescription
apiKeyrequiredYour widget-scoped token
apiUrl'https://inputbuffer.io'The API origin to send to. The widget appends its own paths, so set this to an origin such as http://localhost:8080
attachToNoneA CSS selector for an element that opens the modal on click
title'Share your feedback'The modal heading
placeholder"What's on your mind?"The textarea placeholder text
showTitleFieldfalseShow the optional title field
showSentimentfalseShow the thumbs up/down sentiment selector. The selection drives the modal's own UI. The feedback API has no sentiment field, so recording a vote needs the bar and a target instead
submittedByNoneAn identifier for whoever is submitting, such as your own user id. Sent as submitted_by, up to 300 characters
colorScheme'auto''light', 'dark', or 'auto'
injectStylestrueSet to false to disable automatic CSS injection
themeNoneA theme object. See Theming

createModal takes no target option, unlike createBar. The modal attaches a target per open call, so pass one to modal.open(). See Targets on the modal.

Modal instance methods:

MethodDescription
modal.open(options?)Open the modal, optionally with context. See below
modal.close()Close the modal programmatically
modal.destroy()Clean up and remove all listeners
modal.on('submit', ({ id }) => {})The feedback was submitted. id is the InputBuffer feedback id
modal.on('close', () => {})The modal closed
modal.on('error', (err) => {})The submission failed

Use the id from the submit event to match a widget submission to its entry in your inbox, or to fetch it from the REST API.

Pass options to pre-populate the modal or attach feedback to a specific target:

modal.open({
  title: 'Feedback on this page',        // Override modal heading
  sentiment: 'negative',                 // Pre-select a thumb ('positive' | 'negative')
  submittedBy: 'user_12345',             // Override the submittedBy set on createModal
  prefill: {
    description: 'This section was...',  // Pre-fill textarea
  },
  target: {
    type: 'documentation',
    metadata: {
      page_url: window.location.href,
      section_heading: 'Submit your first feedback',  // optional
    },
  },
});

Targeting

Targets attach feedback to a specific resource in your product: a documentation page, a REST endpoint, or a CLI command. A target lets you see which pages or endpoints draw the most complaints.

You do not register targets ahead of time. Send the type and its metadata, and InputBuffer either finds the matching target or creates it. Two targets of the same type with the same metadata are treated as the same target, which is how votes and feedback accumulate per resource.

Note

Targets are optional for the modal: without one, feedback goes into your general inbox. They matter more for the bar. A thumb click with no target still opens the follow-up form, and anything the user writes there still reaches your inbox, but the vote itself is not recorded anywhere.

Warning

When you set a target, metadata is required, and so are the fields marked below as required for that type. A target missing one is rejected with a 422. The web component drops an incomplete target and logs a warning to the console rather than sending it.

Documentation page

modal.open({
  target: {
    type: 'documentation',
    metadata: {
      page_url: 'https://docs.example.com/getting-started',  // required
      section_heading: 'Authentication',  // optional
      doc_version: 'v2',                  // optional
    },
  },
});

REST API endpoint

modal.open({
  target: {
    type: 'rest_endpoint',
    metadata: {
      method: 'POST',            // required
      path: '/v1/users',         // required
      host: 'api.example.com',   // optional
      api_version: 'v1',         // optional
    },
  },
});

CLI command

modal.open({
  target: {
    type: 'cli_command',
    metadata: {
      command: 'deploy',         // required
      subcommand: 'production',  // optional
      cli_version: '2.4.0',      // optional
      args: ['--env', 'prod'],   // optional
    },
  },
});

Pass more than one entry in args and each flag becomes its own target, so you can see which flag drew the complaint.

Targets on the modal

The modal takes a target when it opens, not when it is created, so every target reaches it through modal.open(). The script tag auto-init calls open() with no arguments, which is why data-api-key and data-attach-to on their own cannot attach one.

A static site can still send targets, with no build step and no npm install. The CDN bundle puts createModal on window.InputBufferIO, so wiring up your own button takes a few lines:

<button id="feedback-btn">Send feedback</button>

<script src="https://cdn.jsdelivr.net/npm/@inputbuffer/[email protected]/dist/modal.js"></script>
<script>
  const modal = window.InputBufferIO.createModal({ apiKey: 'YOUR_WIDGET_TOKEN' });

  document.getElementById('feedback-btn').addEventListener('click', () => {
    modal.open({
      target: { type: 'documentation', metadata: { page_url: window.location.href } },
    });
  });
</script>

Leave data-api-key off the script tag when you do this. With it, the bundle builds a second modal of its own, and if data-attach-to names the same button, a click opens both.

Reach for attachTo and the data-* attributes when you don't need a target, and for the snippet above when you do.

Targets on the web component

<inputbuffer-feedback> builds the same target from target-type plus the metadata attributes for that type:

AttributeApplies toMetadata field
target-typeAlldocumentation, rest_endpoint, or cli_command
target-page-urldocumentationpage_url. Defaults to the current page URL
target-section-headingdocumentationsection_heading
target-doc-versiondocumentationdoc_version
target-methodrest_endpointmethod
target-pathrest_endpointpath
target-hostrest_endpointhost
target-api-versionrest_endpointapi_version
target-commandcli_commandcommand
target-subcommandcli_commandsubcommand
target-cli-versioncli_commandcli_version
target-argscli_commandargs, as a comma separated list

Because target-page-url defaults to the current page, rating the page a reader is on takes one attribute:

<inputbuffer-feedback
  api-key="YOUR_WIDGET_TOKEN"
  label="Was this helpful?"
  target-type="documentation">
</inputbuffer-feedback>

An endpoint needs its identifying fields spelled out:

<inputbuffer-feedback
  api-key="YOUR_WIDGET_TOKEN"
  label="Was this helpful?"
  target-type="rest_endpoint"
  target-method="POST"
  target-path="/v1/users">
</inputbuffer-feedback>

Errors

The error event hands you the failure so you can log it or show your own message. API failures arrive as an ApiError with type, title, status, detail, category, and, on a validation failure, the field that was rejected. Network failures and the 10 second request timeout arrive as an ordinary Error instead.

Switch on type rather than status, because several types share a status code. The full list is in the API Errors reference.

The category value tells you who can fix the problem. The widget treats the two differently:

  • user: the person filling in the form sent something the API rejected, such as text over the length limit. The detail value is written for them, and the widget shows it in the form as-is.
  • integration: the embed itself is misconfigured, such as a full-access token in the browser or an origin that is not allowlisted. The person filling in the form sees a generic message, and the widget logs the real reason to the browser console so you can find it.
import { ApiError } from '@inputbuffer/feedback';

bar.on('error', (err) => {
  if (err instanceof ApiError && err.category === 'integration') {
    console.error('Widget misconfigured:', err.type, err.detail);
  }
});

ApiError is exported from every entry point: @inputbuffer/feedback, /bar, and /modal.

Problem typeStatusWhat went wrong
unauthorized, invalid-token, invalid-token-format401The token is missing, malformed, or revoked
widget-token-restricted403A full-access ib_ token was sent from a browser. Use a widget-scoped ibw_ token
forbidden-origin403This page's origin is not on the token's allowlist. Add it under Settings → API Tokens
usage-limit-reached402The organization hit its lifetime feedback limit
missing-required-field, invalid-field-value422A field is missing or invalid. The field value in the error response names the field that was rejected
rate-limited429Too many requests from this token or IP
internal-error500Something failed on our end

Theming

Color scheme

createModal({ apiKey: '...', colorScheme: 'dark' });
// or 'light' | 'auto' (default: 'auto' follows system preference)

Theme object

Override individual colors via the theme config option:

createModal({
  apiKey: '...',
  theme: {
    primary: '#6366f1',       // Button and focus ring color
    background: '#1e1e2e',    // Modal background
    surface: '#2a2a3e',       // Modal header background
    text: '#cdd6f4',          // Body text
    selected: '#6366f1',      // Selected thumb background
    selectedColor: '#ffffff', // Selected thumb icon color
  },
});

The same theme option is available on createBar(). For the web component, use theme-* attributes:

<inputbuffer-feedback
  api-key="..."
  theme-primary="#6366f1"
  theme-background="#1e1e2e"
  theme-text="#cdd6f4">
</inputbuffer-feedback>

CSS custom properties

When injectStyles is true (default), the widget injects its own stylesheet and exposes CSS custom properties you can override:

/* Modal: set on #ib-modal */
#ib-modal {
  --ib-primary: #6366f1;
  --ib-primary-hover: #4338ca;
  --ib-background: #1e1e2e;
  --ib-surface: #2a2a3e;
  --ib-text: #cdd6f4;
  --ib-muted: #9399b2;
  --ib-border: #45475a;
  --ib-selected: #6366f1;
  --ib-selected-color: #ffffff;
  --ib-radius: 8px;
  --ib-radius-input: 4px;
}

/* Bar: set on .ib-bar-wrapper */
.ib-bar-wrapper {
  --ib-primary: #6366f1;
}

CSS customization

When injectStyles: false, you can style everything from scratch using stable selectors.

SelectorElement
#ib-overlayThe full-screen backdrop
#ib-modalThe modal container, and the scope for the CSS variables
#ib-modal-headerThe header bar
#ib-modal-bodyThe body content area
#ib-titleThe modal heading
#ib-textareaThe feedback textarea
#ib-title-inputThe optional title input
#ib-submitThe submit button
#ib-closeThe close button
#ib-successThe success message
#ib-errorThe error message

Bar selectors

SelectorElement
.ib-bar-wrapperThe outer wrapper, and the scope for the CSS variables
.ib-barThe visible bar strip
.ib-bar-labelThe label text
.ib-bar-btnThe thumb buttons
.ib-bar-popoverThe follow-up popover
.ib-bar-headerThe popover header
.ib-bar-bodyThe popover body
.ib-bar-titleThe popover heading
.ib-bar-textareaThe feedback textarea
.ib-bar-title-inputThe optional title input
.ib-bar-submitThe submit button
.ib-bar-successThe success message
.ib-bar-errorThe error message

Next steps

  • API getting started: submit feedback server-side, query feedback, or integrate with your backend
  • API Errors: every error the API can return, with what causes it and how to recover