> ## Documentation Index
> Fetch the complete documentation index at: https://docs.usepropane.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Embed a research agent

> Embed research agents on your website or share them via link

## Getting started

How to prepare for embedding a research agent on your website.

<Steps>
  <Step title="Grab the ID of the research agent you want to embed">
    This can be found in the URL when you are on the research agent page.
  </Step>

  <Step title="Request a Publishable key">
    A publishable key is similar to an API key, only it is safe to be used on public websites.
  </Step>

  <Step title="Allow access from your domain">
    Together with the publishable key, an allow list of domains acts as security measures to prevent the embed from being used on unwanted domains.
  </Step>
</Steps>

### How?

At the moment, a publishable key can be obtained by contacting us.

You can do this by reaching out directly in a connected Slack channel, or by sending an email to [developer@usepropane.ai](mailto:developer@usepropane.ai)

## Code snippets

Use any of the following code snippets to embed a research agent.

<Tabs>
  <Tab title="Auto start">
    ### Auto start

    Using this code snippet the session will immediately load and render in the given container.

    In addition a session will be created with the provided participant information.

    ```html theme={null}
    <script type="text/javascript" src="https://cdn.usepropane.ai/propane-browser-sdk@latest.js"></script>

    <script type="text/javascript">
      const client = PROPANE_SDK.init({
        publishableKey: "<your_publishable_key>",
      });

      client.embedInterview({
        container: "#interview-container",
        interview: {
          id: "[interview_id]",
          participant: {
            first_name: "Jane",
            last_name: "Doe",
            email: "jane@doe.com",
            //...interview_specific_fields
          }
        }
      });
    </script>
    ```

    <Note>
      Note that the fields in the participant object depends on the template type.

      For a full list of fields please visit our [OpenAPI documentation](https://api.usepropane.ai/v1/docs#/default/get_or_create_interview_session)
    </Note>
  </Tab>

  <Tab title="Manual start">
    ### Manual start

    Using this code snippet the session will only load and render once the participant information is explicitly set at a later stage.

    ```javascript theme={null}
    <script type="text/javascript" src="https://cdn.usepropane.ai/propane-browser-sdk@latest.js"></script>

    <script type="text/javascript">
      (async () => {
        const client = PROPANE_SDK.init({
          publishableKey: "<your_publishable_key>",
        });

        const embeddable = await client.embedInterview({
          container: "#interview-container",
          interview: {
            id: "[interview_id]",
          }
        });

        // Set the participant information later. E.g. on a user interaction
        embeddable.setParticipant({
          first_name: "Jane",
          last_name: "Doe",
          email: "jane@doe.com",
          //...interview_specific_fields
        });
    })();
    </script>
    ```

    <Note>
      Note that the fields in the participant object depends on the template type.

      For a full list of fields, contact [developer@usepropane.ai](mailto:developer@usepropane.ai)
    </Note>
  </Tab>

  <Tab title="Walk-ins">
    ### Walk-ins (custom templates only)

    Any custom research agent can be setup as an open walk-in session.

    This means that anyone can manually sign up to participate.

    To configure the embed to accept signups; replace the `participant` details with `walkin` property to explicitly telling the embed that signups are open.

    ```javascript theme={null}
    <script type="text/javascript" src="https://cdn.usepropane.ai/propane-browser-sdk@latest.js"></script>

    <script type="text/javascript">
      const client = PROPANE_SDK.init({
        publishableKey: "<your_publishable_key>",
      });

      client.embedInterview({
        container: "#interview-container",
        interview: {
          id: "[interview_id]",
          walkin: true
        },
      });
    </script>
    ```
  </Tab>

  <Tab title="Text configuration">
    ### Text configuration

    When embedding, you can configure various options such as text content.

    <Info>
      If custom text content is not provided, the text content provided for the landing page will be used.
    </Info>

    ```javascript theme={null}
    <script type="text/javascript" src="https://cdn.usepropane.ai/propane-browser-sdk@latest.js"></script>

    <script type="text/javascript">
    (async () => {
      const client = PROPANE_SDK.init({
        publishableKey: "<your_publishable_key>",
      });

      const embeddable = await client.embedInterview({
        container: "#interview-container",
        interview: {
          id: "[interview_id]",
          text: {
            introMessageTitle: "Hi there,",
            introMessage: ["Hope you can spare 5 min. to provide some feedback."],
            startButtonLabel: "Sure, let's go",
            thankYouMessageTitle: "Thank You!",
            thankYouMessage: ["We appreciate your time and insights."],
            // For walk-in mode only:
            walkinTitle: "Help us get better",
            walkinMessage: ["Hope you can spare 5 min. to provide some feedback."],
          }
        }
      });

      // Or set the config later
      embeddable.setConfig({ /*...*/ })
    })();
    </script>
    ```
  </Tab>

  <Tab title="Theming">
    ### Theming

    Theme the embedded experience to match your brand identity.

    ```javascript theme={null}
    <script type="text/javascript" src="https://cdn.usepropane.ai/propane-browser-sdk@latest.js"></script>

    <script type="text/javascript">
    (async () => {
      const client = PROPANE_SDK.init({
        publishableKey: "<your_publishable_key>",
      });

      const embeddable = await client.embedInterview({
        container: "#interview-container",
        theme: {
          lumen: "Propane",
          frameBorder: false,
          colors: {
            // Supported color formats: hsl, rgb, rgba, or hex.
            background: "#f2f2f2", 
            foreground: "#333333",
            border: "#e0e0e0",
            button: "#2f516a",
            buttonForeground: "#ffffff",
            secondaryButton: "#949494",
            secondaryButtonForeground: "#ffffff",
          },
        },
        interview: {
          id: "[interview_id]",
        }
      });
    })();
    </script>
    ```

    The "LumenThemeName" is a set of different color themes for the agent avatar

    Choose from the following themes:

    * "Propane"
    * "Serene Blue"
    * "Sunset Orange"
    * "Golden Hour"
    * "Blush Pink"
    * "Purple Love"
  </Tab>
</Tabs>

## Troubleshooting

Important security requirements and considerations when embedding on your website.

<AccordionGroup>
  <Accordion title="Content Security Policy (CSP)" icon="shield-halved">
    If your website uses a Content Security Policy, you'll need to allow the following sources:

    * **script-src**: Add `https://cdn.usepropane.ai` to allow loading the Propane SDK script
    * **frame-src**: Add `https://interview.usepropane.ai` to allow the Propane iframe (`interview.usepropane.ai` is the hosted session host)

    Example CSP header:

    ```http theme={null}
    Content-Security-Policy: script-src 'self' https://cdn.usepropane.ai; frame-src 'self' https://interview.usepropane.ai;
    ```
  </Accordion>

  <Accordion title="Domain Allowlist" icon="list-check">
    Your website's domain must be explicitly allowed. The embed will not load if your domain is not on the allowlist, even with a valid publishable key.

    This security measure prevents unauthorized use on other websites. Make sure to provide all domains (including subdomains) where you plan to embed.
  </Accordion>

  <Accordion title="Third-Party Script Security" icon="lock">
    When embedding third-party scripts, consider the following best practices:

    * The Propane SDK loads from a trusted CDN with HTTPS encryption
    * The script creates an isolated iframe for the session content
    * No sensitive data from your website is accessible to the iframe
  </Accordion>

  <Accordion title="Common Issues" icon="triangle-exclamation">
    If the embed fails to load, check for these common issues:

    * **CSP blocking**: Check browser console for CSP violation errors
    * **Domain not allowlisted**: Verify your with us that the domain is configured correctly
    * **HTTPS requirement**: The embed must be used on HTTPS websites
    * **Container element**: Ensure the target container element exists when the script runs
  </Accordion>
</AccordionGroup>

## Related

* [Email and link distribution](/distribution/email-link-distribution)
* [Adding participants](/interviews/adding-participants)
* [Creating a research agent](/interviews/create-interview)
