Partner Integration Documentation

Add ReimagineHome to your platform

Bring AI property visualization into your platform. Let users stage, redesign, declutter, and enhance property photos directly inside your product.

For a quick end-to-end experience, use the snippet below:

import { reihWidget } from 'reimaginehome-widget';

reihWidget.configure({ public_key: 'public_key' });

await reihWidget.open({
  media: [
    { image_url: 'https://yoursite.com/listings/01.webp' },
  ],
});

Get started with the widget

You'll need a publishable key to initialize the widget. Once you're onboarded, find and rotate keys anytime under Integration in your . Don't have one yet? Reach out and we'll get you set up.

orSend us an email

Then follow the install and usage steps below. Pick CDN for a script-tag embed, or npm for React, Next.js, Vue, or Angular.

Install the widget

NPM

Install the package from npm:

bash
$ npm install reimaginehome-widget

CDN

Load the widget through CDN as follows. Make sure to set your publishable key on the script tag — not inside reihWidgetConfig:

html
<script async
  src="https://widget.styldod.com/widget.js"
  data-public-key="public_key"
  data-mode="simple"
  data-user-id="user-123"
  data-session-id="sess_abc"></script>

Scalar values can also be set via data-mode, data-user-id, and data-session-id on the script tag. Arrays, objects, and callbacks must go through window.reihWidgetConfig, configure(), or open().


Initialize the widget

npm integration

1. Import the widget:

javascript
import { reihWidget } from 'reimaginehome-widget';

The namespaced reihWidget object is the recommended import. The same methods are also available as named exports and a default export, so all three forms below are equivalent:

javascript
// Named functions
import { configure, open, close, destroy } from 'reimaginehome-widget';

// Default export (same instance as the namespaced object)
import reihWidget from 'reimaginehome-widget';

2. Configure once on page load:

Pass your publishable key and any persistent defaults. The widget keeps this until you reconfigure or destroy it.

javascript
reihWidget.configure({
  public_key: 'public_key',
  mode: 'simple',
  sidebar_position: 'right',
  onError: (err) => console.error(err),
  onClose: () => console.log('widget closed'),
});

3. Open on user action:

Call reihWidget.open() when the user clicks your trigger. Pass media here, or set it earlier in configure() and call open() with no arguments.

javascript
await reihWidget.open({
  media: [
    { image_url: 'https://yoursite.com/listings/01.webp' },
    { image_url: 'https://yoursite.com/listings/02.webp' },
  ],
});

4. Close or destroy when done:

Use close() to hide the overlay while keeping the session warm, and destroy() on route change in SPAs. See Session lifecycle for details.

CDN integration

1. Set config before opening:

Assign window.reihWidgetConfig with media and options. The publishable key stays on data-public-key.

javascript
window.reihWidgetConfig = {
  media: [
    { image_url: 'https://yoursite.com/listings/01.webp' },
  ],
  mode: 'simple',
  sidebar_position: 'right',
};

2. Open after the script loads:

After the loader script has loaded, call open(). With media already in reihWidgetConfig, you can call reihWidget.open() with no arguments; pass overrides when you need per-launch changes.

javascript
await window.reihWidget.open();

3. Clean up on page leave:

javascript
window.reihWidget?.destroy();

Widget configuration options

Persistent configuration applied to every open() call until you reconfigure or destroy. Set via reihWidget.configure() (npm) or window.reihWidgetConfig + data-public-key (CDN). Callbacks such as onError and onClose can be set here as well as in open() overrides.

CDN exception. For CDN integrations, public_key is set on the script tag's data-public-key attribute, not inside window.reihWidgetConfig. All other fields below go in the config object.

Configuration params

  • public_key
    requiredstring
    Your publishable key. Set as public_key in configure options or data-public-key on the script tag. Bound to your allowed origins.
  • mode
    optionalstring

    Default: "simple"

    Widget flow mode. Currently supports "simple" only.
  • media
    required
    Non-empty array; required before the first open(). Each item needs a publicly reachable image_url. Optional label sets a display caption. Can be set here, in window.reihWidgetConfig, or passed to open().
    default
    media: [
      { image_url: "https://yoursite.com/listings/01.webp" },
      { image_url: "https://yoursite.com/listings/02.webp", label: "Kitchen" },
    ]
  • branding
    optionalobject

    Default: none

    Logo, heading, colors, typography. See Styling & branding for the sub-fields. Logo and colors can also be managed in the dashboard; heading is code-only.
  • language
    optionalstring

    Default: "en-US"

    BCP 47 locale code for the widget UI (e.g. "en-US", "pl-PL"). Supported values: en-US, en-GB, pl-PL, es-ES. Falls back to your dashboard default language when omitted.
    default
    language: "en-US"
  • sidebar_position
    optionalstring

    Default: "right"

    Which side of the overlay the sidebar mounts on. One of "left" or "right".
  • header / body / footer
    optionalobject

    Default: none

    Optional CTA copy for the widget's header, body, and footer sections — each accepts text, subtext, and actions_label. Pair with onActionClick to run your own handler (e.g. open a lead form) on the host page when a section button is clicked. Defaults can also be set in the dashboard.
    default
    body: {
      text: "Love this look?",
      subtext: "Talk to an agent about this listing.",
      actions_label: "Contact agent",
    }
  • listing_id
    optionalstring
    Your own identifier for the listing the widget is opened on. Echoed in events for attribution.
  • user_id
    optionalstring
    Your own analytics identifier for the end user. Echoed in events.
  • session_id
    optionalstring
    Your own reference id for this user's flow. Distinct from the widget's internal session.

Launch the widget

reihWidget.open(overrides?) is async and returns a Promise. The effective config is merged from configure(), window.reihWidgetConfig, and any overrides you pass. A non-empty media array must be present in that merged config before the widget can open.

reihWidget.open() overrides

  • media
    optional
    Non-empty array required in the effective config when open() runs. Omit here if you already set media via configure() or window.reihWidgetConfig. Each item needs a publicly reachable image_url; optional label sets a display caption.
    default
    media: [
      { image_url: "https://yoursite.com/listings/01.webp" },
      { image_url: "https://yoursite.com/listings/02.webp", label: "Kitchen" },
    ]
  • mode
    optionalstring
    Override the configured mode. Currently supports "simple" only.
  • branding
    optionalobject
    Override the persistent branding. Useful for multi-brand portals.
  • language
    optionalstring
    Override the UI locale (e.g. "pl-PL").
  • sidebar_position
    optionalstring
    Override the sidebar position. One of "left" or "right".
  • onError
    optionalfunction
    Callback invoked with { message, code? } when something goes wrong during the session.
  • onClose
    optionalfunction
    Callback invoked when the modal closes.
  • onActionClick
    optionalfunction
    Callback invoked with the section slug ("header", "body", or "footer") when the user clicks that section's action button. Runs on your host page, so use it to open a contact form, route to a listing, or fire your own analytics.

Session lifecycle

Two helpers cover the session after reihWidget.open():

javascript
reihWidget.close();    // hide modal, keep session warm
reihWidget.destroy();  // tear down completely — use on SPA route change

Control integration defaults from the Dashboard

Most of what the widget shows can be managed without shipping code from your . Settings you save there become your organization's defaults and apply to every session automatically — so you can re-brand, switch the default language, or adjust limits centrally without a redeploy.

Code overrides dashboard defaults. Anything you pass to configure() or open() takes precedence for that session, so you can let the dashboard own the baseline and override per-launch when you need to (e.g. multi-brand portals).

  • Branding & theme — logo, primary/secondary and text colors, typography, default language, and header, body, and footer CTA copy.
  • AI & providers — choose a provider and bring your own API key per AI capability.
  • Limits & quotas — generation volume, rate limits, and client overrides.
  • Integration — publishable keys, allowed domains (origins), and the embed snippet.
  • Team — invite teammates to your organization and manage their roles.

Rotate and revoke publishable keys

Publishable keys are managed under Integration in your . Each key shows its current status: Active, Grace (still valid but expiring), Expired, or Revoked.

Graceful rotation

Issues a new key while your current key stays valid for a grace period you set, so you can update your integration without interruption. The previous key expires automatically when the grace period ends.

  1. Select Rotate key → Graceful rotation and choose a grace period.
  2. Copy the new publishable key and secret key.
  3. Update data-public-key (CDN) or configure({ public_key }) (npm) with the new key before the grace period ends.

Immediate rotation

Issues a new key and revokes your existing key immediately, with no grace period. Use this when a key has been compromised. Any integration still using the previous key stops working at once.

Revoke a key

Revokes a single key immediately, without issuing a replacement. At least one usable key must remain, so revoke is unavailable when only one key is active — rotate instead.

The secret key is shown only once. Store it securely when it appears — it cannot be retrieved later. If it is lost, rotate again to issue a new pair.

Customize branding and appearance

The widget renders inside its own overlay and isn't styleable by your page CSS — but it accepts a constrained set of branding tokens so it can match your visual identity. You can set these in code via branding, or manage them visually under Branding & Theme in your .

What you can customize

  • Primary color — buttons, highlights, and focus states. Pass any hex value that meets WCAG AA contrast with white text.
  • Secondary color — accents, borders, and supporting UI elements via branding.colors.secondary.
  • Text colour — heading and body text via branding.colors.text_primary and branding.colors.text_secondary.
  • Font — widget typography via branding.typography.font_family and optional font_url for custom or Google Fonts.
  • Heading text — the headline at the top of the widget via branding.heading in code only (not in the dashboard). Defaults to "Reimagine".
  • Brand logo— your organization's logo via branding.logo in code, or upload a PNG in the dashboard.
  • Language — default UI locale via language in code (e.g. "en-US") or under Branding & Theme in the dashboard.
  • Style choices— the AI workflow options users see (staging, redesign, decluttering, exterior refresh, and more) are determined per session from room-type detection and your organization's backend configuration — not from host integration code.

Example

javascript
reihWidget.configure({
  public_key: 'public_key',
  branding: {
    logo: 'https://yoursite.com/logo.png',
    heading: 'Restyle this room',
    colors: {
      primary: '#1F6F4A',
      secondary: '#03A1AC',
      text_primary: '#071121',
      text_secondary: '#555555',
    },
    typography: {
      font_family: "'Inter', sans-serif",
      font_url: 'https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&display=swap',
    },
  },
  language: 'en-US',
});

Need something beyond this list?

We're open to additional branding and workflow customization for enterprise partners. Reach out and we'll work through what's possible for your platform.