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://app.getkoji.com/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.

For a step-by-step walkthrough of embedding your first interview, see Using the Embed Widget.


iframe URL Parameters

Append these as query parameters to the embed URL:

ParameterTypeDefaultDescription
themestringlightVisual 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
languagestringProject defaultLanguage code (e.g., en, es, fr)
modestringProject defaultInterview mode: text or voice
metadatastringURL-encoded JSON object of custom metadata
guide_idstringDefault guideSpecific interview guide to use
auto_startbooleanfalseAutomatically starts the interview when the widget loads

Example with Parameters

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

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://app.getkoji.com');

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://app.getkoji.com') 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 Koji.


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://app.getkoji.com/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 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://app.getkoji.com.
  • 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