New

Now in Claude, ChatGPT, Cursor & more with our MCP server

Back to docs
API Reference

Embed Widget Reference

Technical reference for the Koji embed widget including iframe parameters and PostMessage API.

Embed Widget Reference

The Koji embed widget lets you place an interactive interview directly inside your website or application using an iframe. This reference covers every parameter, the PostMessage API for two-way communication, and styling options.


Basic Embed Code

The simplest embed uses a single iframe tag:

<iframe
  src="https://koji.so/api/v1/embed/:project_id"
  width="400"
  height="600"
  frameborder="0"
  allow="microphone"
></iframe>

Replace :project_id with your actual project ID. The allow="microphone" attribute is required if your interview uses voice mode.


iframe URL Parameters

Append these as query parameters to the embed URL:

ParameterTypeDefaultDescription
themestringdarkVisual theme: light or dark
accent_colorstringProject defaultHex color code without the hash (e.g., 4F46E5)
hide_headerbooleanfalseHides the widget header bar
hide_brandingbooleanfalseRemoves Koji branding from the widget (requires Growth+ plan)
respondent_namestringPre-fills the respondent name
respondent_emailstringPre-fills the respondent email
external_idstringYour own identifier for the respondent, useful for linking back to your system
languagestringProject defaultLanguage code (e.g., en, es, fr)
modestringProject defaultInterview mode: text or voice
metadatastringURL-encoded JSON object of custom metadata
auto_startbooleanfalseAutomatically starts the interview when the widget loads

Using external_id

The external_id parameter lets you pre-fill a respondent identifier from your own system. This is useful for tracking which of your users completed the interview without requiring them to enter information manually. It is passed through to webhooks, exports, and the API responses.

<iframe
  src="https://koji.so/api/v1/embed/a1b2c3d4?external_id=user_12345"
  width="400"
  height="600"
  frameborder="0"
></iframe>

Example with Parameters

<iframe
  src="https://koji.so/api/v1/embed/a1b2c3d4?theme=dark&accent_color=4F46E5&respondent_name=Jane&auto_start=true"
  width="400"
  height="600"
  frameborder="0"
  allow="microphone"
></iframe>

Structured Question Widgets

When your research brief includes structured questions, the embed widget automatically renders interactive input widgets during the interview. These include:

  • Scale widgets — sliders or number selectors for rating questions
  • Choice widgets — radio buttons for single choice, checkboxes for multiple choice
  • Ranking widgets — drag-and-drop lists for ranking questions
  • Yes/No widgets — toggle buttons for binary questions

The widgets are styled to match your theme and accent color settings. Responses from these widgets are captured as structured data, enabling quantitative analysis alongside the qualitative conversation.


PostMessage API

The embed widget communicates with your host page via the browser's postMessage API. This enables two-way interaction: you can send commands to the widget, and the widget sends events back to you.

Sending Commands to the Widget

Use postMessage on the iframe's content window:

const iframe = document.getElementById('koji-embed');

// Start the interview programmatically
iframe.contentWindow.postMessage({
  type: 'koji:start',
  payload: {
    respondent_name: 'Jane Doe',
    metadata: { source: 'homepage' }
  }
}, 'https://koji.so');

Available Commands

Command TypePayloadDescription
koji:start{ respondent_name?, respondent_email?, metadata? }Starts the interview with optional respondent info
koji:complete{}Ends the interview and triggers analysis
koji:set_theme{ theme: 'light' | 'dark' }Changes the theme dynamically
koji:set_accent{ color: '#4F46E5' }Changes the accent color dynamically
koji:reset{}Resets the widget to its initial state

Receiving Events from the Widget

Listen for messages from the iframe:

window.addEventListener('message', (event) => {
  if (event.origin !== 'https://koji.so') return;

  const { type, payload } = event.data;

  switch (type) {
    case 'koji:ready':
      console.log('Widget is loaded and ready');
      break;
    case 'koji:interview_started':
      console.log('Interview started:', payload.interview_id);
      break;
    case 'koji:interview_completed':
      console.log('Interview completed:', payload.interview_id);
      break;
    case 'koji:error':
      console.error('Widget error:', payload.message);
      break;
  }
});

Available Events

Event TypePayloadWhen It Fires
koji:ready{}Widget has loaded and is ready to accept commands
koji:interview_started{ interview_id }An interview session has begun
koji:message_sent{ message_count }The respondent sent a message
koji:interview_completed{ interview_id, stats }The interview has ended
koji:error{ code, message }An error occurred in the widget
koji:resize{ width, height }The widget's ideal size changed (useful for responsive containers)

Always check event.origin before processing messages to ensure they come from https://koji.so.


Responsive Sizing

The embed widget adapts to the dimensions you give it, but works best within certain ranges:

DimensionMinimumRecommendedMaximum
Width320px400px100% of container
Height500px600px100% of viewport

For a responsive layout, use CSS to make the iframe fluid:

<div style="width: 100%; max-width: 480px; height: 70vh; min-height: 500px;">
  <iframe
    src="https://koji.so/api/v1/embed/:project_id"
    style="width: 100%; height: 100%; border: none; border-radius: 12px;"
    allow="microphone"
  ></iframe>
</div>

Listen for koji:resize events to dynamically adjust the container size based on the widget's content.


Styling and Branding

The widget defaults to a dark theme. Use ?theme=light in the URL to switch to light mode. The default border-radius is 12px.

The widget respects your branding settings configured in the project dashboard. Beyond that, the URL parameters let you override theme and accent color per embed instance.

The iframe itself can be styled with CSS on the host page:

#koji-embed {
  border: none;
  border-radius: 12px;
  box-shadow: 0 4px 24px rgba(0, 0, 0, 0.1);
}

Hiding Koji branding with hide_branding=true requires a Growth plan or higher.


Security Considerations

  • Always validate event.origin when listening for PostMessage events. Only accept messages from https://koji.so.
  • Do not pass sensitive data through URL parameters. Use the PostMessage API for any information you do not want visible in the URL.
  • The allow attribute should only include microphone if your interview uses voice mode. Do not grant unnecessary permissions.

Browser Support

The embed widget works in all modern browsers. Voice features perform best in Chrome and Edge. See Browser Compatibility for the full support matrix.


Next Steps

Related Articles

API Authentication

Learn how to authenticate with the Koji API using API keys and Bearer tokens.

User Research API: Embed AI Interviews into Any Product or Workflow

How to use Koji's User Research API to run AI-moderated interviews from your own backend. Covers REST endpoints, the embed widget, webhooks, authentication, rate limits, and headless interview patterns.

Using the Embed Widget

Add a Koji interview to your website using an embeddable iframe with configuration options and event listeners.

Headless API Overview

Manage interviews programmatically with the Koji REST API — start, message, and complete interviews from your own code.

In-App AI Surveys: Embedded Customer Research Inside Your Product

Embed adaptive AI interviews directly into your product to capture in-the-moment customer feedback. A complete guide to in-app AI surveys, triggers, and implementation with Koji.

Structured Questions in AI Interviews

Mix quantitative data collection — scales, ratings, multiple choice, ranking — with AI-powered conversational follow-up in a single interview.

In-Product Research Recruiting: Recruit Customer Interview Participants From Inside Your App

Stop paying recruiting panels for participants you already have. Learn how to recruit research participants directly from your product using embedded prompts, in-app banners, email triggers, and personalized AI interview links. Faster, cheaper, and more representative than external panels — with zero scheduling friction.

Cancel-Flow Exit Interviews: AI Moderation That Saves Churning Users

Replace your single-textarea cancellation survey with an AI-moderated exit interview that probes the real reason people leave and triggers save offers in real time.