Everything on this page applies equally whether the widget is added through the snippet or through the WordPress plugin. The plugin only loads the same hosted script described below; it does not change what the widget can reach or collect.
How it talks to the backend
The widget is anonymous. There is no login step, no user account, and no session cookie involved. Instead:- Every request the widget makes is sent to a dedicated widget endpoint on
api.baseUrl, never directly to the underlying service. - Your
tenantIdtravels with each request as anX-Tenant-Idheader, identifying which organization’s catalog and branding to use. - That endpoint checks the requested path and method against a fixed allowlist before forwarding anything. Requests outside the allowlist are rejected.
- Starting and continuing a chat, reading chat messages, cancelling a request, and resolving a clarifying question
- Reading material records and datasheets
- Reading catalog reference data such as families, manufacturers, colors, brands, and property definitions
- Reading citations
- Listing countries and states for the quote form
- Submitting a guest quote
- Posting widget telemetry
The allowlist is the boundary. It contains only anonymous catalog reads, chat operations, and the guest quote submission, so account, order, project, and administrative endpoints are not reachable through the widget path.
Cross-origin access and the tenant ID
The widget endpoints and the widget script are served with permissive cross-origin headers so the bundle can be loaded and called from your own domain. There is currently no per-origin restriction on the widget endpoints, so a request carrying your tenant ID is accepted from any origin.Streaming responses
Answers stream over Server-Sent Events. When a conversation starts, the widget opens a long-lived connection for that chat and receives a sequence of typed events:
Browsers cannot attach custom headers to an SSE connection, so on the streaming connection only, the tenant ID is passed as a query parameter instead of a header.
If the stream goes quiet while a response is still in flight, the widget falls back to periodically refetching the conversation, so a dropped connection degrades to slower updates rather than a stuck screen.
Telemetry
What is collected
The widget buffers two kinds of events and periodically sends them to yourapi.baseUrl:
Timings. Named performance milestones with a timestamp, such as when the bundle finished loading, when the interface rendered, when the streaming connection opened, when the first answer token arrived, and when the answer finished rendering.
Actions. Named interaction events with a small structured context. The events currently emitted are:
- A message-sent event, whose context records the chat identifier, whether files were attached, whether a shortcut was used, and which search mode was selected.
- A diagnostic trace event, whose context records internal trace identifiers for the completed answer, used to correlate a slow or failed response with backend logs.
- Error events, whose context records the error text and where in the widget it occurred.
What is not collected
- No message content. The text a visitor types and the text the assistant replies with are never included in a telemetry event.
- No identity. There is no sign-in, so no user account, email, or name is attached to telemetry. The session identifier is a random value generated fresh each time the widget bundle loads on a page; it is not persisted, and it does not link one page view to another.
- No third-party analytics. The embedded bundle does not include the platform’s product analytics SDK. Telemetry goes only to your configured
api.baseUrl.
Personal data does reach the platform when a visitor voluntarily submits a quote request. That is the quote form’s own payload, described in Overview, and it is separate from telemetry.