# SDK Reference (/docs) Customer Agent exposes a browser SDK for controlling the Messenger from host pages and applications: open it, close it, pass identity and context, read support and interview state, resolve sessions, and subscribe to events. These pages are reference-first. They describe the public contract with enough detail for a developer or AI assistant to plan an integration: entrypoints, options, method signatures, event payloads, return values, and direct effects. ## Start Here [#start-here] * [Script entry](/docs/entrypoints/script): `window.CustomerAgent` * [ESM entry](/docs/entrypoints/esm): `@customer-agent/sdk` * [Options](/docs/sdk/configuration): `CustomerAgentOptions` * [Methods](/docs/sdk/methods): `boot`, `update`, `show`, `hide`, `toggle`, `shutdown`, `identify`, `setContext`, `on`, `openEntry`, `getState`, `getSession`, `getSupportState`, `getInterviewState`, `getInterviewSession`, `ensureInvitation`, `startInvitation`, `chooseInvitation`, `sendInterviewMessage`, `loadInterviewReward` * [Identity and context](/docs/sdk/context): `WidgetUser`, `WidgetContextJson`, `SetContextOptions` * [Events](/docs/sdk/events): event names and payloads * [Support and interview sessions](/docs/sdk/sessions): support/interview state, targets, and session methods * [React](/docs/sdk/react): React hook exports * [AI docs](/docs/resources/ai): `llms.txt`, `llms-full.txt`, and markdown endpoints SDK imports have no server-side side effects. Methods that control the Messenger are browser behavior. # ESM entry (/docs/entrypoints/esm) The ESM entry is the package-import version of the SDK. It exposes the same browser singleton as the script entry, plus React hooks and message catalog assets. ## Package Exports [#package-exports] | Export path | Exports | Purpose | | ----------------------------------- | ----------------------------------------------------------------------------- | --------------------------------- | | `@customer-agent/sdk` | `default`, `CustomerAgent`, named SDK methods, types, `CUSTOMER_AGENT_EVENTS` | Browser SDK control surface. | | `@customer-agent/sdk/react` | `useCustomerAgent`, `useCustomerAgentState`, `useCustomerAgentEvent` | React hook surface. | | `@customer-agent/sdk/sdk.js` | Browser script asset | Script SDK file. | | `@customer-agent/sdk/runtime.es.js` | Browser runtime asset | Public runtime module artifact. | | `@customer-agent/sdk/messages/*` | Message catalog JSON files | Built-in locale message catalogs. | ## Main Export [#main-export] ```ts import CustomerAgent, { CUSTOMER_AGENT_EVENTS, boot, chooseInvitation, ensureInvitation, getInterviewState, getInterviewSession, getSession, getState, getSupportState, hide, identify, openEntry, on, loadInterviewReward, sendInterviewMessage, setContext, show, shutdown, startInvitation, toggle, update } from "@customer-agent/sdk" ``` See [JavaScript SDK](/docs/sdk/methods) for method signatures. ## Type Exports [#type-exports] | Type | Meaning | | ------------------------------- | ------------------------------------------ | | `CustomerAgentGlobal` | Command function and method namespace. | | `CustomerAgentOptions` | Options accepted by `boot` and `update`. | | `CustomerAgentWidget` | Controller returned by `boot`. | | `CustomerAgentState` | State returned by `getState`. | | `CustomerAgentSupportState` | State returned by `getSupportState`. | | `CustomerAgentInterviewState` | State returned by `getInterviewState`. | | `CustomerAgentTarget` | Target accepted by `show` and `toggle`. | | `CustomerAgentEventMap` | Event payload map. | | `CustomerAgentEventName` | Union of event names. | | `SetContextOptions` | Options accepted by `setContext`. | | `CustomerAgentInterviewSession` | Session returned by `getInterviewSession`. | | `WidgetContextJson` | JSON object accepted as user context. | ## Message Catalog Exports [#message-catalog-exports] Built-in message catalogs are available under `@customer-agent/sdk/messages/.json`. ## Self-hosted Assets [#self-hosted-assets] When serving built SDK files yourself, publish the complete `dist` output instead of copying individual entry files. | Locale | Export path | | ------- | ----------------------------------------- | | `de` | `@customer-agent/sdk/messages/de.json` | | `en` | `@customer-agent/sdk/messages/en.json` | | `es` | `@customer-agent/sdk/messages/es.json` | | `fr` | `@customer-agent/sdk/messages/fr.json` | | `it` | `@customer-agent/sdk/messages/it.json` | | `ja` | `@customer-agent/sdk/messages/ja.json` | | `ko` | `@customer-agent/sdk/messages/ko.json` | | `pt-BR` | `@customer-agent/sdk/messages/pt-BR.json` | | `zh` | `@customer-agent/sdk/messages/zh.json` | | `zh-TW` | `@customer-agent/sdk/messages/zh-TW.json` | # Script entry (/docs/entrypoints/script) The script entry is the browser-global version of the SDK. It exposes one global, `window.CustomerAgent`, which is both a command function and a method namespace. ```ts window.CustomerAgent: CustomerAgentGlobal ``` ## Command Forms [#command-forms] | Form | Shape | Return | | ------------ | ---------------------------------------- | ------------------------------ | | Command call | `window.CustomerAgent(command, ...args)` | Command-specific return value. | | Method call | `window.CustomerAgent.boot(options)` | Method-specific return value. | The command names and method names match the [JavaScript SDK](/docs/sdk/methods) reference. ## Script Attributes [#script-attributes] When the script element has `data-app-id`, the SDK boots the Messenger from script attributes. ```html ``` | Attribute | Type | Effect | | --------------- | --------------------------------- | ----------------------------------------- | | `data-app-id` | `string` | Sets `CustomerAgentOptions.app_id`. | | `data-open` | `"true" \| "false"` | Sets `open_on_init`; only `"true"` opens. | | `data-position` | `"bottom-right" \| "bottom-left"` | Sets default launcher position. | ## Global API [#global-api] `window.CustomerAgent` supports the same command form and methods as the ESM SDK. | API | Reference | | ------- | ----------------------------------- | | Methods | [JavaScript SDK](/docs/sdk/methods) | | Options | [Options](/docs/sdk/configuration) | | Events | [Events](/docs/sdk/events) | # AI docs (/docs/resources/ai) Use these entry points when an AI assistant, coding agent, or editor plugin needs Customer Agent SDK documentation as plain text. They are generated from the same public reference pages in this site. ## AI Accessible Documentation [#ai-accessible-documentation] Structured index of public documentation pages. Point an AI tool here for a quick map. Complete public documentation in one text file for full-context assistant reads. Add .md to any docs page URL to get raw markdown content, for example /docs/sdk/methods.md. ## Context Files [#context-files] Add this to project context files such as `CLAUDE.md`, `AGENTS.md`, or editor rules when an assistant will edit a host application that embeds Customer Agent. ```md ## Customer Agent This project uses Customer Agent for web support and interview messaging. Documentation: https://your-docs-host.example.com/llms-full.txt Key SDK references: - Entrypoints: /docs/entrypoints/script.md and /docs/entrypoints/esm.md - Methods: /docs/sdk/methods.md - Options: /docs/sdk/configuration.md - Identity and context: /docs/sdk/context.md - Events: /docs/sdk/events.md - Support/interview sessions: /docs/sdk/sessions.md - React hooks: /docs/sdk/react.md ``` ## Page Markdown [#page-markdown] Every public docs page has a markdown form. Common paths: ```txt /docs/entrypoints/script.md /docs/entrypoints/esm.md /docs/sdk/methods.md /docs/sdk/configuration.md /docs/sdk/context.md /docs/sdk/events.md /docs/sdk/sessions.md /docs/sdk/react.md ``` # Options (/docs/sdk/configuration) ## CustomerAgentOptions [#customeragentoptions] ```ts type WidgetLauncherVariableName = | "bg-color" | "color" | "border-color" | "border-radius" | "border-style" | "border-width" | "box-shadow" | "hover-bg-color" | "hover-color" | "hover-border-color" | "hover-border-radius" | "hover-border-style" | "hover-border-width" | "hover-box-shadow" type WidgetLauncherVariables = Partial< Record > type WidgetHeaderOptions = { close?: boolean menu?: boolean } type WidgetPageOptions = { customerOrigin?: string pagePath?: string pageUrl?: string } type CustomerAgentOptions = { app_id: string anonymous_id?: string brand?: { name?: string } context?: WidgetContextJson context_ready?: boolean header?: WidgetHeaderOptions launcher?: { target?: HTMLElement | string placement?: "top" | "right" | "bottom" | "left" offset?: number style?: Record variables?: WidgetLauncherVariables } locale?: string messages?: WidgetLocaleMessages mobile?: { mode?: "fullscreen" | "bottom-sheet" } mount?: HTMLElement | string open_on_init?: boolean page?: WidgetPageOptions position?: "bottom-right" | "bottom-left" theme?: { colorScheme?: "light" | "dark" | "system" primaryColor?: string radius?: number } user?: WidgetUser } ``` ## Fields [#fields] | Option | Type | Required | Effect | Notes | | --------------------- | ----------------------------------------------- | -------- | ------------------------------------------------------- | --------------------------------------------------------------------- | | `app_id` | `string` | Yes | Customer Agent app identifier. | Missing values throw. | | `anonymous_id` | `string` | No | Stable logged-out visitor identifier. | Used before a known user id is available. | | `brand.name` | `string` | No | Messenger brand display name. | Overrides configured brand name. | | `context` | `WidgetContextJson` | No | Initial user context. | Later updates can use `setContext`. | | `context_ready` | `boolean` | No | Initial context readiness. | Later updates can use `setContext(..., { ready })`. | | `header.close` | `boolean` | No | Controls the panel close action. | Enabled unless set to `false`. | | `header.menu` | `boolean` | No | Controls the header more-options menu. | Enabled unless set to `false`. | | `launcher.target` | `HTMLElement \| string` | No | Host element used as launcher. | Selector misses fall back to default launcher. | | `launcher.placement` | `"top" \| "right" \| "bottom" \| "left"` | No | Desktop panel placement. | Applies to launcher anchoring. | | `launcher.offset` | `number` | No | Desktop panel offset in pixels. | Negative values are clamped to zero. | | `launcher.style` | `Record` | No | Inline style fields for the default launcher container. | `color` also applies to the default launcher button. | | `launcher.variables` | `WidgetLauncherVariables` | No | Default launcher button style variables. | Values are resolved from the host document before iframe application. | | `locale` | `string` | No | Locale override. | Omit to use host locale resolution. | | `messages` | `WidgetLocaleMessages` | No | UI message overrides. | Partial message map. | | `mobile.mode` | `"fullscreen" \| "bottom-sheet"` | No | Mobile presentation preference. | See [Mobile presentation](#mobile-presentation). | | `mount` | `HTMLElement \| string` | No | Mount target. | Selector misses fall back to `document.body`. | | `open_on_init` | `boolean` | No | Opens Messenger after boot. | Does not emit `widget.opened`. | | `page.customerOrigin` | `string` | No | Page origin metadata sent with conversation context. | Overrides automatic page origin detection. | | `page.pagePath` | `string` | No | Page path metadata sent with conversation context. | Overrides automatic page path detection. | | `page.pageUrl` | `string` | No | Page URL metadata sent with conversation context. | Overrides automatic page URL detection. | | `position` | `"bottom-right" \| "bottom-left"` | No | Default launcher position. | Applies to the SDK default launcher. | | `theme.colorScheme` | `"light" \| "dark" \| "system"` | No | Color scheme. | Messenger UI theme preference. | | `theme.primaryColor` | `string` | No | Primary color. | CSS color string. | | `theme.radius` | `number` | No | Corner radius. | Numeric radius value. | | `user` | `WidgetUser` | No | Initial visitor identity. | Use `user.id` for a stable logged-in user id. | ## Related Types [#related-types] | Type | Reference | | ---------------------- | ----------------------------------------------------------- | | `WidgetUser` | [Identity and context](/docs/sdk/context#widgetuser) | | `WidgetContextJson` | [Identity and context](/docs/sdk/context#widgetcontextjson) | | `WidgetLocaleMessages` | Message keys listed below. | ## Page Metadata [#page-metadata] `page.customerOrigin`, `page.pagePath`, and `page.pageUrl` override the page metadata that the SDK detects from the current browser location. These fields are sent as conversation context metadata. They do not change `context`; user-defined context values remain under `userContext`. ## Header [#header] `header.close` controls the panel-level close action in the top-right corner. When it is `false`, the Messenger does not render that close action. This is useful for mounted or WebView integrations where the host app owns navigation and dismissal. `header.menu` controls the more-options menu in Messenger headers. When it is `false`, support and interview headers do not render the menu action. When omitted or `true`, the menu action is available when that header has menu items. ## Mobile Presentation [#mobile-presentation] `mobile.mode` controls the Messenger presentation selected for mobile viewports. Setting `mobile.mode` does not force wider viewports to use a mobile presentation. | Value | Effect | | ---------------- | -------------------------------------------------------------------------------------- | | `"fullscreen"` | Uses the desktop presentation on wider viewports and fullscreen on mobile viewports. | | `"bottom-sheet"` | Uses the desktop presentation on wider viewports and bottom-sheet on mobile viewports. | When a non-mounted Messenger opens in fullscreen presentation, the SDK prevents the host page from scrolling behind the Messenger. Host page scrolling is restored when the Messenger closes, shuts down, or updates away from fullscreen presentation. When `mount` is set, the SDK treats the Messenger as mounted content and does not lock host page scrolling. ## Launcher Styling [#launcher-styling] `launcher.variables` customizes the SDK default launcher button inside its iframe. The option accepts only the short keys listed below; unsupported keys have no effect. Values may reference host CSS custom properties, such as `"var(--primary)"`. The SDK resolves the value from the host document before applying it to the default launcher iframe. ```ts launcher: { variables: { "bg-color": "var(--primary)", color: "var(--primary-foreground)", "hover-bg-color": "var(--primary-hover)" } } ``` | Variable | Effect | | --------------------- | ----------------------- | | `bg-color` | Base background color. | | `color` | Base icon/text color. | | `border-color` | Base border color. | | `border-radius` | Base border radius. | | `border-style` | Base border style. | | `border-width` | Base border width. | | `box-shadow` | Base box shadow. | | `hover-bg-color` | Hover background color. | | `hover-color` | Hover icon/text color. | | `hover-border-color` | Hover border color. | | `hover-border-radius` | Hover border radius. | | `hover-border-style` | Hover border style. | | `hover-border-width` | Hover border width. | | `hover-box-shadow` | Hover box shadow. | `launcher.style` is the public inline style map for the SDK default launcher container. Its `color` field also sets the default launcher button color inside the iframe. `CustomerAgentOptions` does not declare `launcher.className`. Class names applied to host-side elements and containers do not style the default launcher button inside the iframe. For iframe button styling, use `launcher.variables` or public inline style fields such as `launcher.style.color`. ## Launcher Geometry [#launcher-geometry] The Messenger panel opens from the resolved launcher position. On desktop, expanded and collapsed sizes resize from that launcher anchor while respecting viewport safe space. ## WidgetLocaleMessages [#widgetlocalemessages] | Key | Default meaning | Placeholders | | ------------------------------- | --------------------------------- | ------------ | | `add_emoji` | Emoji picker label. | None | | `assistant_author_ai` | AI assistant author label. | None | | `assistant_author_human` | Human support author label. | None | | `attachment_label` | Attachment button label. | None | | `close_chat` | Close action label. | None | | `collapse_window` | Collapse action label. | None | | `download_transcript` | Transcript download action label. | None | | `expand_window` | Expand action label. | None | | `input_placeholder` | Support composer placeholder. | None | | `interview_input_placeholder` | Interview composer placeholder. | None | | `interview_session_description` | Interview header description. | None | | `launcher_close` | Launcher close label. | `{title}` | | `launcher_open` | Launcher open label. | `{title}` | | `message_aria_label` | Message ARIA label. | None | | `more_options` | More options action label. | None | | `relative_time_today` | Today label. | None | | `relative_time_yesterday` | Yesterday label. | None | | `relative_time_day` | Relative day label. | `{count}` | | `relative_time_hour` | Relative hour label. | `{count}` | | `relative_time_minute` | Relative minute label. | `{count}` | | `relative_time_now` | Current-time label. | None | | `remove_attachment` | Attachment removal label. | `{name}` | | `send_message` | Send message action label. | None | | `status_reply_time` | Reply-time status copy. | None | | `support_chat_label` | Messenger ARIA label. | `{title}` | | `welcome_message` | Initial welcome message. | None | # Identity and context (/docs/sdk/context) ## WidgetUser [#widgetuser] ```ts type WidgetUser = { id?: string email?: string name?: string [key: string]: unknown } ``` Used by `CustomerAgentOptions.user` and `identify(user)`. | Field | Type | Effect | | --------------- | --------- | ---------------------- | | `id` | `string` | Stable user id. | | `email` | `string` | User email. | | `name` | `string` | User display name. | | Additional keys | `unknown` | Extra identity fields. | `user.id` is the signed-in user identity for support session continuity and interview availability. `email`, `name`, and additional user fields are user context fields, not session identity. Use `anonymous_id` in `CustomerAgentOptions` for logged-out visitor continuity before a signed-in `user.id` is available. ## WidgetContextJson [#widgetcontextjson] ```ts type WidgetContextJson = Record ``` Used by `CustomerAgentOptions.context` and `setContext(context, options)`. Context is a JSON object. Nested plain objects merge recursively when `merge` is not `false`; non-object values replace the previous value at the same key. ## SetContextOptions [#setcontextoptions] ```ts type SetContextOptions = { merge?: boolean ready?: boolean } ``` | Option | Type | Default | Effect | | ------- | --------- | -------------- | -------------------------------------------- | | `merge` | `boolean` | `true` | Merges with existing context unless `false`. | | `ready` | `boolean` | Previous value | Updates the SDK context readiness flag. | ## Methods [#methods] | Method | Argument type | Effect | | --------------------------------------- | ---------------------- | ---------------------------------- | | `identify(user)` | `WidgetUser` | Updates visitor identity. | | `setContext(context)` | `WidgetContextJson` | Merges user context. | | `setContext(context, { merge: false })` | `WidgetContextJson` | Replaces user context. | | `boot({ user, context })` | `CustomerAgentOptions` | Sets initial identity and context. | # Events (/docs/sdk/events) ## Subscribe [#subscribe] ```ts on( eventName: TEventName, handler: (event: CustomerAgentEventMap[TEventName]) => void ): () => void ``` The return value unsubscribes the handler. ## Base Payload [#base-payload] Every event includes these fields. | Field | Type | Meaning | | ----------- | ------------------------ | ---------------------- | | `type` | `CustomerAgentEventName` | Event name. | | `appId` | `string` | Customer Agent app id. | | `widgetId` | `string` | Runtime instance id. | | `timestamp` | `string` | ISO timestamp. | ## Conversation Payload [#conversation-payload] Conversation and message events include conversation metadata when available. | Field | Type | Meaning | | ----------------------- | ------------------------------------ | ----------------------------- | | `conversationId` | `string` | Conversation identifier. | | `conversationType` | `"support" \| "interview" \| string` | Conversation product surface. | | `entryId` | `string` | Conversation entry id. | | `supportConversationId` | `string` | Support conversation id. | | `interviewSessionId` | `string` | Interview session id. | ## Event Names [#event-names] `CUSTOMER_AGENT_EVENTS` exposes these stable string values. | Event | Additional payload | Effect | | ----------------------------- | --------------------------------------------------------------------- | ------------------------------------------------- | | `widget.ready` | None | Messenger UI is ready. | | `widget.opened` | None | Messenger opened. | | `widget.closed` | None | Messenger closed. | | `widget.expanded` | None | Messenger expanded. | | `widget.collapsed` | None | Messenger collapsed. | | `conversation.created` | Conversation payload | A support or interview conversation was created. | | `transcript.downloaded` | Conversation type, `messageCount`, optional conversation payload | A support or interview transcript was downloaded. | | `support.state_changed` | `support: CustomerAgentSupportState` | Support state changed. | | `support.handoff_requested` | Optional conversation payload | Human handoff was requested. | | `support.feedback_submitted` | Optional conversation payload, optional `messageId` | Message feedback was submitted. | | `support.bug_reported` | Optional conversation payload | Bug report was submitted. | | `interview.state_changed` | `interview: CustomerAgentInterviewState` | Interview state changed. | | `interview.available` | Available interview state fields | An interview invitation is available. | | `interview.invitation_shown` | `campaignId`, `entryId`, `invitationId` | An interview invitation was shown. | | `interview.invitation_later` | `campaignId`, `entryId`, `invitationId` | The invitation was deferred. | | `interview.invitation_closed` | `campaignId`, `entryId`, `invitationId` | The invitation was closed. | | `interview.session_started` | Conversation payload | An interview session started. | | `interview.session_completed` | Conversation payload, optional `status` | An interview session completed. | | `interview.reward_updated` | Optional conversation payload, optional `reward` | Interview reward data changed. | | `message.sent` | Optional conversation payload, `messageId`, `role` | User or assistant message submitted. | | `message.send_failed` | Optional conversation payload, optional `messageId`, `role` | Message request failed before completion. | | `message.started` | Conversation payload, optional `messageId`, `role` | Message response started. | | `message.completed` | Conversation payload, `messageId`, `role`, optional `assistantAuthor` | Message response completed. | | `message.failed` | Optional conversation payload, optional `messageId`, `role` | Message response failed. | | `message.retry` | Optional conversation payload, optional `messageId`, `role` | Message retry requested. | | `error` | `message` | SDK error reported. | `role` is `"assistant"` or `"user"`. `assistantAuthor`, when present, is `"llm"` or `"human"`. `transcript.downloaded` always includes `conversationType`, which is `"support"` for support transcripts and `"interview"` for interview transcripts. Handoff, feedback, bug report, and retry are public event names and are emitted only when the matching Messenger behavior exists. The declared message payload type keeps `role` as `"assistant" | "user"`; current response lifecycle events are emitted for assistant responses. ## Event Types [#event-types] | Type | Shape | | ------------------------ | ------------------------------------ | | `CustomerAgentEventName` | Union of public event names. | | `CustomerAgentEventMap` | Map from event name to payload type. | # JavaScript SDK (/docs/sdk/methods) ## Command Function [#command-function] ```ts CustomerAgent(command, ...args) ``` The command function also exposes method properties such as `CustomerAgent.boot(...)` and named ESM exports such as `boot(...)`. ## Methods [#methods] | Method | Signature | Returns | Effect | | ---------------------- | ----------------------------------------------------------- | --------------------------------------------------------- | ------------------------------------ | | `boot` | `(options: CustomerAgentOptions)` | `CustomerAgentWidget` | Initializes the Messenger singleton. | | `update` | `(options: Partial)` | `void` | Applies public option updates. | | `identify` | `(user: WidgetUser)` | `void` | Updates visitor identity. | | `setContext` | `(context: WidgetContextJson, options?: SetContextOptions)` | `void` | Merges or replaces user context. | | `show` | `(target?: CustomerAgentTarget)` | `void` | Opens the Messenger target. | | `hide` | `()` | `void` | Closes the Messenger. | | `toggle` | `(target?: CustomerAgentTarget)` | `void` | Toggles Messenger visibility. | | `openEntry` | `(entryId: string)` | `void` | Opens a conversation entry id. | | `on` | `(eventName: CustomerAgentEventName, handler)` | `() => void` | Subscribes to an SDK event. | | `getState` | `()` | `CustomerAgentState \| null` | Reads current singleton state. | | `getSession` | `()` | `Promise<{ conversationId: string } \| null>` | Ensures the support session. | | `getSupportState` | `()` | `CustomerAgentSupportState \| null` | Reads support session state. | | `getInterviewState` | `()` | `CustomerAgentInterviewState \| null` | Reads interview state. | | `getInterviewSession` | `()` | `CustomerAgentInterviewSession \| null` | Reads the active interview session. | | `ensureInvitation` | `()` | `Promise<{ invitationId: string } \| null>` | Creates or returns an invitation id. | | `startInvitation` | `(invitationId: string)` | `Promise<{ entryId: string; sessionId: string } \| null>` | Starts an interview session. | | `chooseInvitation` | `(invitationId: string, choice: "close" \| "later")` | `Promise` | Records an invitation choice. | | `sendInterviewMessage` | `(content: string)` | `Promise` | Sends an active interview message. | | `loadInterviewReward` | `(sessionId?: string)` | `Promise` | Loads interview reward data. | | `shutdown` | `()` | `void` | Removes the Messenger singleton. | ## Method Details [#method-details] ### boot [#boot] Initializes the Messenger singleton from `CustomerAgentOptions` and returns a `CustomerAgentWidget` controller for that instance. Calling `boot` again replaces the previous singleton. ### update [#update] Applies public option changes to the current singleton. The argument is `Partial`. `context` is accepted as an option field, but `setContext` is the dedicated context method. Updating `mobile.mode` recalculates the Messenger presentation; when an open non-mounted Messenger leaves fullscreen presentation, host page scrolling is restored. ### identify [#identify] Updates visitor identity from a `WidgetUser`. Identity fields are also included in conversation context. ### setContext [#setcontext] Updates `WidgetContextJson`. By default, plain object fields merge with existing context. Passing `{ merge: false }` replaces the existing context object. Passing `{ ready }` updates the context readiness flag. ### show, hide, toggle, openEntry [#show-hide-toggle-openentry] `show(target)` opens the Messenger. `hide()` closes it. `toggle(target)` switches visibility and updates the target when one is provided. `openEntry(entryId)` opens a specific conversation entry. See [Support and interview sessions](/docs/sdk/sessions#customeragenttarget) for target shapes. ### on [#on] Subscribes a handler to a `CustomerAgentEventName`. The return value removes that handler. A `widget.ready` handler subscribed after readiness is emitted receives a replayed ready event. ### getState [#getstate] Returns the current `CustomerAgentState`, or `null` when no singleton exists. ### getSession and getSupportState [#getsession-and-getsupportstate] `getSession()` ensures the support conversation session and resolves `{ conversationId }`. `getSupportState()` reads the support state without starting a session. See [Support state](/docs/sdk/sessions#support-state). ### Interview methods [#interview-methods] `getInterviewState()` reads interview availability/session state. `getInterviewSession()` returns the active interview session snapshot or `null`. `ensureInvitation()`, `startInvitation(...)`, `chooseInvitation(...)`, `sendInterviewMessage(...)`, and `loadInterviewReward(...)` control the interview session surface. See [Interview methods](/docs/sdk/sessions#interview-methods). ### shutdown [#shutdown] Removes the current Messenger singleton. ## Commands [#commands] | Command | Arguments | Return | | ------------------------ | ------------------------------------------------- | --------------------------------------------------------- | | `"boot"` | `CustomerAgentOptions` | `CustomerAgentWidget` | | `"update"` | `Partial` | `void` | | `"identify"` | `WidgetUser` | `void` | | `"setContext"` | `WidgetContextJson`, optional `SetContextOptions` | `void` | | `"show"` | Optional `CustomerAgentTarget` | `void` | | `"hide"` | None | `void` | | `"toggle"` | Optional `CustomerAgentTarget` | `void` | | `"openEntry"` | `string` | `void` | | `"on"` | `CustomerAgentEventName`, handler | `() => void` | | `"getState"` | None | `CustomerAgentState \| null` | | `"getSession"` | None | `Promise<{ conversationId: string } \| null>` | | `"getSupportState"` | None | `CustomerAgentSupportState \| null` | | `"getInterviewState"` | None | `CustomerAgentInterviewState \| null` | | `"getInterviewSession"` | None | `CustomerAgentInterviewSession \| null` | | `"ensureInvitation"` | None | `Promise<{ invitationId: string } \| null>` | | `"startInvitation"` | `string` | `Promise<{ entryId: string; sessionId: string } \| null>` | | `"chooseInvitation"` | `string`, `"close" \| "later"` | `Promise` | | `"sendInterviewMessage"` | `string` | `Promise` | | `"loadInterviewReward"` | Optional `string` | `Promise` | | `"shutdown"` | None | `void` | ## CustomerAgentWidget [#customeragentwidget] `boot` returns a controller for the current Messenger instance. Top-level state reads return `null` when no singleton exists. Widget controller methods are typed as instance methods; reads that require an initialized singleton throw `CustomerAgent widget is not initialized.` if the controller cannot resolve one. `getInterviewSession()` can return `null` when the widget is initialized and no interview session is active. | Method | Signature | Effect | | ---------------------- | --------------------------------------------------------------------------- | ------------------------------------ | | `chooseInvitation` | `(invitationId: string, choice: "close" \| "later") => Promise` | Records an invitation choice. | | `ensureInvitation` | `() => Promise<{ invitationId: string }>` | Creates or returns an invitation id. | | `getInterviewState` | `() => CustomerAgentInterviewState` | Reads interview state. | | `getInterviewSession` | `() => CustomerAgentInterviewSession \| null` | Reads active interview session. | | `getSession` | `() => Promise<{ conversationId: string }>` | Resolves the support session. | | `getState` | `() => CustomerAgentState` | Reads instance state. | | `getSupportState` | `() => CustomerAgentSupportState` | Reads support state. | | `hide` | `() => void` | Closes the Messenger. | | `identify` | `(user: WidgetUser) => void` | Updates visitor identity. | | `on` | `(eventName: CustomerAgentEventName, handler) => () => void` | Subscribes to an event. | | `openEntry` | `(entryId: string) => void` | Opens a conversation entry id. | | `loadInterviewReward` | `(sessionId?: string) => Promise` | Loads interview reward data. | | `sendInterviewMessage` | `(content: string) => Promise` | Sends an active interview message. | | `setContext` | `(context: WidgetContextJson, options?: SetContextOptions) => void` | Updates user context. | | `show` | `(target?: CustomerAgentTarget) => void` | Opens the Messenger target. | | `shutdown` | `() => void` | Removes the Messenger instance. | | `startInvitation` | `(invitationId: string) => Promise<{ entryId: string; sessionId: string }>` | Starts an interview session. | | `toggle` | `(target?: CustomerAgentTarget) => void` | Toggles Messenger visibility. | | `update` | `(options: Partial) => void` | Applies public option updates. | ## CustomerAgentState [#customeragentstate] | Field | Type | Meaning | | --------------------------- | ---------------------------------- | ------------------------------------------- | | `activeEntryId` | `string \| undefined` | Active conversation entry id. | | `activeTarget` | `CustomerAgentTarget \| undefined` | Active Messenger target. | | `appId` | `string` | Customer Agent app id. | | `isOpen` | `boolean` | Messenger visibility. | | `isReady` | `boolean` | Whether the Messenger can be opened. | | `interview` | `CustomerAgentInterviewState` | Current interview state. | | `launcher.targetConfigured` | `boolean` | Whether a launcher target was configured. | | `launcher.targetConnected` | `boolean` | Whether the configured target is connected. | | `support` | `CustomerAgentSupportState` | Current support state. | | `widgetId` | `string` | Runtime instance id. | # SDK surfaces (/docs/sdk/overview) ## Surfaces [#surfaces] The SDK has three public surfaces. They point at the same browser singleton, so the choice is about how host code reaches the API: script global, package import, or React hooks. | Surface | Entry | Purpose | | ----------- | --------------------------- | ----------------------------------------------- | | Script SDK | `window.CustomerAgent` | Browser global command function. | | ESM SDK | `@customer-agent/sdk` | Browser SDK package entry. | | React hooks | `@customer-agent/sdk/react` | React access to SDK state, methods, and events. | ## Public Exports [#public-exports] | Export | Type | Purpose | | --------------------------- | ------------------------------------------------------------------------------------- | ---------------------------------------------- | | `default` / `CustomerAgent` | `CustomerAgentGlobal` | Command function and method namespace. | | `boot` | `(options: CustomerAgentOptions) => CustomerAgentWidget` | Initializes the Messenger singleton. | | `update` | `(options: Partial) => void` | Applies public option updates. | | `show` / `hide` / `toggle` | `(target?: CustomerAgentTarget) => void` for `show`/`toggle`; `() => void` for `hide` | Controls Messenger visibility. | | `openEntry` | `(entryId: string) => void` | Opens a conversation entry id. | | `shutdown` | `() => void` | Removes the Messenger singleton. | | `identify` | `(user: WidgetUser) => void` | Updates visitor identity. | | `setContext` | `(context: WidgetContextJson, options?: SetContextOptions) => void` | Updates user context. | | `on` | `(eventName, handler) => () => void` | Subscribes to SDK events. | | `getState` | `() => CustomerAgentState \| null` | Reads singleton state. | | `getSession` | `() => Promise<{ conversationId: string } \| null>` | Ensures the support session. | | `getSupportState` | `() => CustomerAgentSupportState \| null` | Reads support session state. | | `getInterviewState` | `() => CustomerAgentInterviewState \| null` | Reads interview state. | | `getInterviewSession` | `() => CustomerAgentInterviewSession \| null` | Reads active interview session data. | | `ensureInvitation` | `() => Promise<{ invitationId: string } \| null>` | Creates or returns an interview invitation id. | | `startInvitation` | `(invitationId: string) => Promise<{ entryId: string; sessionId: string } \| null>` | Starts an interview session. | | `chooseInvitation` | `(invitationId: string, choice: "close" \| "later") => Promise` | Records an invitation choice. | | `sendInterviewMessage` | `(content: string) => Promise` | Sends an active interview message. | | `loadInterviewReward` | `(sessionId?: string) => Promise` | Loads interview reward data. | | `CUSTOMER_AGENT_EVENTS` | constant | Stable event names. | SDK imports have no server-side side effects. SDK control methods are browser behavior. # React (/docs/sdk/react) React hooks are exported from `@customer-agent/sdk/react`. ## Exports [#exports] | Hook | Signature | Returns | Effect | | ----------------------- | ----------------------------------- | --------------------------- | ------------------------------------------------------- | | `useCustomerAgent` | `() => CustomerAgentHookController` | Controller and state fields | Reads SDK state and exposes SDK methods. | | `useCustomerAgentState` | `() => CustomerAgentState \| null` | Current state snapshot | Subscribes to SDK ready and visibility changes. | | `useCustomerAgentEvent` | `(eventName, handler) => void` | `void` | Subscribes to an SDK event for the component lifecycle. | ## useCustomerAgent Return [#usecustomeragent-return] | Field | Type | Meaning | | ---------------------- | --------------------------------------------- | --------------------------- | | `CustomerAgent` | `CustomerAgentGlobal` | Raw SDK command function. | | `boot` | `CustomerAgentGlobal["boot"]` | SDK `boot`. | | `chooseInvitation` | `CustomerAgentGlobal["chooseInvitation"]` | SDK `chooseInvitation`. | | `ensureInvitation` | `CustomerAgentGlobal["ensureInvitation"]` | SDK `ensureInvitation`. | | `getInterviewSession` | `CustomerAgentGlobal["getInterviewSession"]` | SDK `getInterviewSession`. | | `getInterviewState` | `CustomerAgentGlobal["getInterviewState"]` | SDK `getInterviewState`. | | `getSession` | `CustomerAgentGlobal["getSession"]` | SDK `getSession`. | | `getState` | `CustomerAgentGlobal["getState"]` | SDK `getState`. | | `getSupportState` | `CustomerAgentGlobal["getSupportState"]` | SDK `getSupportState`. | | `hide` | `CustomerAgentGlobal["hide"]` | SDK `hide`. | | `identify` | `CustomerAgentGlobal["identify"]` | SDK `identify`. | | `isOpen` | `boolean` | Current open state. | | `isReady` | `boolean` | Current ready state. | | `launcher` | `CustomerAgentState["launcher"] \| null` | Current launcher state. | | `launcherAnchor` | `HTMLElement \| null` | Current host launcher node. | | `launcherAnchorRef` | `React.RefObject` | Ref for the host launcher. | | `loadInterviewReward` | `CustomerAgentGlobal["loadInterviewReward"]` | SDK `loadInterviewReward`. | | `on` | `CustomerAgentGlobal["on"]` | SDK `on`. | | `openEntry` | `CustomerAgentGlobal["openEntry"]` | SDK `openEntry`. | | `sendInterviewMessage` | `CustomerAgentGlobal["sendInterviewMessage"]` | SDK `sendInterviewMessage`. | | `setContext` | `CustomerAgentGlobal["setContext"]` | SDK `setContext`. | | `show` | `CustomerAgentGlobal["show"]` | SDK `show`. | | `shutdown` | `CustomerAgentGlobal["shutdown"]` | SDK `shutdown`. | | `startInvitation` | `CustomerAgentGlobal["startInvitation"]` | SDK `startInvitation`. | | `state` | `CustomerAgentState \| null` | Current state snapshot. | | `toggle` | `CustomerAgentGlobal["toggle"]` | SDK `toggle`. | | `update` | `CustomerAgentGlobal["update"]` | SDK `update`. | ## Hook Details [#hook-details] ### useCustomerAgent [#usecustomeragent] Returns SDK methods plus derived state fields. `isOpen`, `isReady`, and `launcher` are convenience fields from `state`. Support and interview methods are also flattened on the returned controller. `launcherAnchor` and `launcherAnchorRef` expose the host-side launcher element currently used as the Messenger anchor. With a custom launcher, this is the resolved `launcher.target` element. With the SDK default launcher, this is the SDK-created host launcher container, not the button inside the launcher iframe. `launcherAnchor` updates React rendering when the anchor changes; `launcherAnchorRef.current` stores the same element for event handlers and effects. ### useCustomerAgentState [#usecustomeragentstate] Returns the latest `CustomerAgentState` snapshot, or `null` before a singleton exists. The hook refreshes on SDK ready/open/close events. ### useCustomerAgentEvent [#usecustomeragentevent] Subscribes to an SDK event for the component lifecycle. The handler receives the typed event payload for the selected event name. # Support and interview sessions (/docs/sdk/sessions) The SDK exposes support and interview session state so a host page can read the active Messenger surface and subscribe to state events. Session methods use the same command function, method namespace, and widget controller forms documented in [JavaScript SDK](/docs/sdk/methods). ## CustomerAgentTarget [#customeragenttarget] `show(target)` and `toggle(target)` accept an optional target. `openEntry(entryId)` is the direct entry-id form. ```ts type CustomerAgentTarget = | { type: "entry"; entryId: string } | { type: "home" } | { type: "interview"; campaignId?: string; sessionId?: string } | { type: "support" } ``` | Target | Effect | | ---------------------------------- | --------------------------------------- | | `{ type: "support" }` | Opens the support conversation entry. | | `{ type: "interview" }` | Opens the interview surface. | | `{ type: "interview", sessionId }` | Opens an interview session target. | | `{ type: "entry", entryId }` | Opens a specific conversation entry id. | | `{ type: "home" }` | Opens the panel home route. | ## Support State [#support-state] ```ts type CustomerAgentSupportState = | { status: "idle" | "starting" | "refreshing" | "error"; error?: { message: string } } | { status: "ready"; conversationId: string } ``` | Method | Returns | Effect | | ------------------- | --------------------------------------------- | ------------------------------------------------ | | `getSupportState()` | `CustomerAgentSupportState \| null` | Reads current support state. | | `getSession()` | `Promise<{ conversationId: string } \| null>` | Ensures and returns the support conversation id. | The widget controller returned by `boot` exposes non-null `getSupportState()` and `getSession()` instance methods. The top-level singleton methods return `null` when no singleton is initialized. ## Interview State [#interview-state] ```ts type CustomerAgentInterviewState = | { status: "idle" | "checking" | "unavailable" | "error"; error?: { message: string } } | { status: "available" campaignId: string title: string body: string startCta: string laterCta: string } | { status: "active"; entryId: `interview/session/${string}`; sessionId: string; title?: string } | { status: "terminal" sessionId: string sessionStatus: "abandoned" | "aborted" | "completed" | "dismissed" } ``` | Status | Meaning | | ------------- | ------------------------------------- | | `idle` | No active interview state. | | `checking` | Interview availability is being read. | | `available` | An interview invitation is available. | | `active` | An interview session is active. | | `terminal` | The interview session ended. | | `unavailable` | No interview invitation is available. | | `error` | The interview request failed. | ## Interview Methods [#interview-methods] | Method | Returns | Effect | | ---------------------------------------- | --------------------------------------------------------- | ------------------------------------------------------- | | `getInterviewState()` | `CustomerAgentInterviewState \| null` | Reads current interview state. | | `getInterviewSession()` | `CustomerAgentInterviewSession \| null` | Reads the active interview session snapshot. | | `ensureInvitation()` | `Promise<{ invitationId: string } \| null>` | Creates or returns the current invitation id. | | `startInvitation(invitationId)` | `Promise<{ entryId: string; sessionId: string } \| null>` | Starts an interview session from an invitation. | | `chooseInvitation(invitationId, choice)` | `Promise` | Records an invitation choice of `"close"` or `"later"`. | | `sendInterviewMessage(content)` | `Promise` | Sends a message in the active interview session. | | `loadInterviewReward(sessionId?)` | `Promise` | Loads reward data for an interview session. | `ensureInvitation()` rejects when no interview invitation is available. `sendInterviewMessage()` rejects when no interview session is active. `loadInterviewReward()` rejects when no session id is available. ## CustomerAgentInterviewSession [#customeragentinterviewsession] ```ts type CustomerAgentInterviewSession = { sessionId: string status: "active" | "abandoned" | "aborted" | "completed" | "dismissed" messages: Array<{ id: string role: "assistant" | "user" content: string createdAt: string }> } ```