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:
| Parameter | Type | Default | Description |
|---|---|---|---|
theme | string | dark | Visual theme: light or dark |
accent_color | string | Project default | Hex color code without the hash (e.g., 4F46E5) |
hide_header | boolean | false | Hides the widget header bar |
hide_branding | boolean | false | Removes Koji branding from the widget (requires Growth+ plan) |
respondent_name | string | — | Pre-fills the respondent name |
respondent_email | string | — | Pre-fills the respondent email |
external_id | string | — | Your own identifier for the respondent, useful for linking back to your system |
language | string | Project default | Language code (e.g., en, es, fr) |
mode | string | Project default | Interview mode: text or voice |
metadata | string | — | URL-encoded JSON object of custom metadata |
auto_start | boolean | false | Automatically 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 Type | Payload | Description |
|---|---|---|
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 Type | Payload | When 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:
| Dimension | Minimum | Recommended | Maximum |
|---|---|---|---|
| Width | 320px | 400px | 100% of container |
| Height | 500px | 600px | 100% 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.originwhen listening for PostMessage events. Only accept messages fromhttps://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
allowattribute should only includemicrophoneif 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.