Skip to content

Embed Client Reference

Copy page

This page is the full surface area of the embed script. Use the Overview for install and orientation; this page is the lookup table.

These attributes are read off the <script> tag itself. Unknown divinci-* / data-divinci-* / known data-experiment-* attributes produce a console warning, so typos surface quickly during integration.

AttributeTypeRequiredDescription
divinci-release-idstring (8–64 alphanumeric)Yes (auto-mount)The release that drives the chat. Required to auto-mount; if omitted, the script loads but does not create a default chat.
data-global-namestringNoName of the window global the script exposes. Default "DIVINCI_AI".
css-srcURLNoPublicly-reachable stylesheet URL passed into the iframe for theming. Must be a parseable URL.
debugflagNoWhen present (or ="true"), enables verbose console logs in the embed script and forwarded into the iframe.
divinci-external-userflag or JWT stringNotrue or empty value enables external-login mode (you’ll call chat.auth.login(jwt)). Passing a JWT value enables external login and logs in immediately on auto-mount.
product-recommendationsflagNoEnable inline product recommendation UI inside chat.
metricsflagNoEnable in-chat metrics surfacing.
help-requestsflagNoEnable help-request CTAs.
notificationsflagNoEnable notification surfacing inside the embed.
context-bubblesflagNoRender RAG context bubbles next to assistant messages.
message-feedbackflagNoShow thumbs-up/down and a feedback dropdown on assistant replies.
quick-menuflagNoEnable the in-chat quick menu.
share-chatflagNoEnable share-this-chat affordance.
data-experiment-idstringNoExperiment identifier. When set with a variant, the embed reports the assignment.
data-experiment-variant"control" | "treatment"NoAssigned variant for the experiment. Unknown values are ignored.

Flag values: an attribute being present (with no value, ="true", or any non-"false" value) is treated as enabled. Only ="false" disables it.

When the script loads, it exposes one global keyed by data-global-name (default DIVINCI_AI):

type DivinciAIGlobal = {
version: string; // package version of the embed
DivinciChat: typeof DivinciChat; // class for manual mounts
createChat: (opts: CreateDivinciChatOptions) => DivinciChat;
DEFAULT_CHAT: DivinciChat | null; // populated after window.load if auto-mount succeeds
};

DEFAULT_CHAT is null until the load event has fired (or stays null if divinci-release-id was missing).

Use this when you want a chat that isn’t auto-mounted, or you want a second chat instance on the page.

const chat = window.DIVINCI_AI.createChat({
releaseId: "rel_your-release-id",
toggleable: false,
contextBubbles: true,
});
document.body.appendChild(chat.iframe);
await chat.waitForReady();
OptionTypeDefaultWhen to use
releaseIdstring— (required)Identifies which release configuration drives the chat (model, system prompt, RAG, theme).
cssSrcstring (URL)undefinedPublicly-reachable stylesheet for white-label theming inside the iframe. Must be a valid URL or the constructor throws.
debugbooleanfalseVerbose logging across the script and iframe bridge.
externalUserbooleanfalseEnables the auth sub-API. When false, chat.auth is null.
productRecommendationsbooleanfalseRenders inline product cards in assistant responses.
toggleablebooleanfalseWhen true, renders a floating launcher / overlay. When false, you mount chat.iframe wherever you want and chat.ui is null.
metricsbooleanfalseEnables metrics surfacing inside the embed.
helpRequestsbooleanfalseEnables help-request CTAs.
notificationsbooleanfalseEnables notifications inside the embed.
contextBubblesbooleanfalseRenders RAG context bubbles.
messageFeedbackbooleanfalseShows thumbs-up/down + feedback dropdown on assistant replies.
quickMenubooleanfalseEnables the in-chat quick menu.
shareChatbooleanfalseEnables share-this-chat affordance.
experimentIdstringundefinedExperiment identifier for A/B reporting.
experimentVariant"control" | "treatment"undefinedAssigned variant.

Note on auto-mount defaults: when the script auto-mounts using script-tag attributes, it forces toggleable: true. Manual createChat calls default toggleable to false.

class DivinciChat {
readonly chat: BasicChat; // underlying chat controller
readonly iframe: HTMLIFrameElement; // mount this where you want chat to appear
readonly auth: ExternalLogin | null; // present when externalUser: true
readonly ui: ToggleableChat | null; // present when toggleable: true
waitForReady(): Promise<void>;
openSharedChat(shareToken: string): void; // jumps the iframe to a shared-conversation deep link
destroy(): void; // tear down the chat, auth, and ui
}
  1. Construct. new DivinciChat({...}) or createChat({...}) synchronously creates chat.iframe. The iframe is not yet attached to the DOM.
  2. Mount. Append chat.iframe to a container, or — for the auto-mounted toggleable: true case — the script handles the mount.
  3. Wait for ready. await chat.waitForReady() resolves once the in-iframe app has booted and the message bridge is connected.
  4. (Optional) log in. If externalUser: true, call chat.auth.login(jwt, opts?) once you have a user JWT.
  5. (Optional) shared chat. chat.openSharedChat(token) redirects the iframe to a 64-hex shared-conversation URL.
  6. Destroy. chat.destroy() tears down the iframe, message bridge, auth, and UI affordances. Call this on SPA route changes when the chat should go away.
  • releaseId is required — empty releaseId.
  • Invalid cssSrccssSrc is not a parseable URL.

Present only when externalUser: true. Manage your end-user identity in the embed.

interface ExternalLogin {
readonly user: User | null;
readonly isLoggedIn: boolean;
readonly tierConfig: TierConfig | null;
readonly onUserChange: EventListener<[User | null]>;
login(jwt: string, options?: LoginOptions): Promise<LoginResult>;
logout(): Promise<void>;
getCurrentUser(): User | null;
}
type LoginOptions = {
tier?: "free" | "basic" | "premium" | "enterprise" | "unlimited";
pricingTier?: "non_member" | "gold_member" | "platinum_member" | "diamond_member";
metadata?: Record<string, unknown>;
};
type LoginResult = {
user: { id: string };
tierConfig: TierConfig; // tier, limits, usage, remaining, pricingTier
};

The tier you pass in LoginOptions is a request — the server validates and may return a different tier in tierConfig. pricingTier is a BigCommerce-only hint for which price band to display.

Example: log in once the host page knows the user:

const chat = window.DIVINCI_AI.DEFAULT_CHAT;
await chat.waitForReady();
const result = await chat.auth.login(myJwt, { tier: "premium" });
console.log("logged in as", result.user.id, "tier:", result.tierConfig.tier);
// Subscribe — calling the event returns an unsubscribe function
const unsubscribe = chat.auth.onUserChange((user) => {
console.log("user changed:", user);
});
// later: unsubscribe();

Present only when toggleable: true. Controls the floating launcher / overlay.

interface ToggleableChat {
readonly isOpen: boolean;
toggleChat(): void;
openChat(): void;
closeChat(): void;
onToggle: EventListener<[boolean]>;
}

Example: programmatically open chat from a “Need help?” button on your page:

document.querySelector("#help-button").addEventListener("click", () => {
window.DIVINCI_AI.DEFAULT_CHAT?.ui?.openChat();
});
window.DIVINCI_AI.DEFAULT_CHAT?.ui?.onToggle((isOpen) => {
console.log("chat is now", isOpen ? "open" : "closed");
});

The underlying chat controller, primarily exposed for state observation.

interface BasicChat {
readonly state: "not-ready" | "getting-ready" | "error" | "ready" | "destroyed";
readonly onStateChange: EventListener<["not-ready" | "getting-ready" | "error" | "ready" | "destroyed"]>;
waitForReady(): Promise<void>;
}

chat.waitForReady() on the top-level DivinciChat delegates to this.

chat.openSharedChat(token) navigates the iframe to a read-only shared-conversation URL. The token is validated client-side as a 64-character lowercase hex string; an invalid token throws Invalid share token — must be a 64-character hex string. The shared chat becomes a fork the moment the user sends a message.

const chat = window.DIVINCI_AI.createChat({ releaseId: "rel_..." });
document.body.appendChild(chat.iframe);
await chat.waitForReady();
chat.openSharedChat("abc123...token..."); // 64 hex chars

Theming happens inside the iframe — your host-page CSS cannot reach it. Two surface areas:

  • cssSrc attribute / option: points to a stylesheet hosted at a publicly-reachable URL. The embed loads it inside the iframe and applies its rules. Use this for white-label color, typography, spacing, and component overrides.
  • CSS variables exposed by the embed app: the embed exposes themeable CSS variables that cssSrc stylesheets can override. The current set is documented in your release’s white-label configuration in the Divinci dashboard.

The launcher button (when toggleable: true) and floating overlay are styled by the embed app itself; theme them via cssSrc.

HookWhen it fires
chat.chat.onStateChangeEvery transition between not-ready / getting-ready / ready / error / destroyed.
chat.auth.onUserChangeAfter successful login, logout, or external token refresh.
chat.ui.onToggleEvery time the toggleable overlay opens or closes.

Each hook is an EventListener<[Args]> from @divinci-ai/embed-shared. It is a callable: invoking it with a handler subscribes and returns an unsubscribe function. Equivalent .on(handler) / .off(handler) methods are also available.

// Subscribe (callable form) — returns an unsubscribe function
const unsubscribe = chat.ui.onToggle((isOpen) => { /* ... */ });
unsubscribe();
// Or use the explicit methods
const handler = (isOpen) => { /* ... */ };
chat.ui.onToggle.on(handler);
chat.ui.onToggle.off(handler);