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.
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:
$ npm install reimaginehome-widgetCDN
Load the widget through CDN as follows. Make sure to set your publishable key on the script tag — not inside reihWidgetConfig:
<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:
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:
// 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.
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.
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.
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.
await window.reihWidget.open();3. Clean up on page leave:
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_keyrequiredstringYour publishable key. Set as
public_keyin configure options ordata-public-keyon the script tag. Bound to your allowed origins. - modeoptionalstring
Default: "simple"
Widget flow mode. Currently supports"simple"only. - mediarequiredNon-empty array; required before the first
open(). Each item needs a publicly reachableimage_url. Optionallabelsets a display caption. Can be set here, inwindow.reihWidgetConfig, or passed toopen().defaultmedia: [ { image_url: "https://yoursite.com/listings/01.webp" }, { image_url: "https://yoursite.com/listings/02.webp", label: "Kitchen" }, ] - brandingoptionalobject
Default: none
Logo, heading, colors, typography. See Styling & branding for the sub-fields. Logo and colors can also be managed in the dashboard;headingis code-only. - languageoptionalstring
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.defaultlanguage: "en-US" - header / body / footeroptionalobject
Default: none
Optional CTA copy for the widget's header, body, and footer sections — each acceptstext,subtext, andactions_label. Pair withonActionClickto 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.defaultbody: { text: "Love this look?", subtext: "Talk to an agent about this listing.", actions_label: "Contact agent", } - listing_idoptionalstringYour own identifier for the listing the widget is opened on. Echoed in events for attribution.
- user_idoptionalstringYour own analytics identifier for the end user. Echoed in events.
- session_idoptionalstringYour 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
- mediaoptionalNon-empty array required in the effective config when
open()runs. Omit here if you already setmediaviaconfigure()orwindow.reihWidgetConfig. Each item needs a publicly reachableimage_url; optionallabelsets a display caption.defaultmedia: [ { image_url: "https://yoursite.com/listings/01.webp" }, { image_url: "https://yoursite.com/listings/02.webp", label: "Kitchen" }, ] - modeoptionalstringOverride the configured mode. Currently supports
"simple"only. - brandingoptionalobjectOverride the persistent branding. Useful for multi-brand portals.
- languageoptionalstringOverride the UI locale (e.g.
"pl-PL"). - onErroroptionalfunctionCallback invoked with
{ message, code? }when something goes wrong during the session. - onCloseoptionalfunctionCallback invoked when the modal closes.
- onActionClickoptionalfunctionCallback 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():
reihWidget.close(); // hide modal, keep session warm
reihWidget.destroy(); // tear down completely — use on SPA route changeControl 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.
- Select Rotate key → Graceful rotation and choose a grace period.
- Copy the new publishable key and secret key.
- Update
data-public-key(CDN) orconfigure({ 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_primaryandbranding.colors.text_secondary. - Font — widget typography via
branding.typography.font_familyand optionalfont_urlfor custom or Google Fonts. - Heading text — the headline at the top of the widget via
branding.headingin code only (not in the dashboard). Defaults to"Reimagine". - Brand logo— your organization's logo via
branding.logoin code, or upload a PNG in the dashboard. - Language — default UI locale via
languagein 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
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.