response-chat-widget backend enforces
these independently. Custom backends must implement their own equivalent authorization.
Credentials and ownership
Widget signatures use
STATESET_WIDGET_AUTH_SECRET. Tokens have either
orgId.agentId.timestamp.signature or orgId.agentId.timestamp.siteId.signature; the site
claim is signed and UUID-shaped. Tenant hints in headers or request metadata must agree with
verified claims; they cannot grant ownership. The public session issuer
binds those claims to server configuration and checks an exact allowed Origin.
That identifies the deployment, not the visitor’s identity.
When a conversation is created, its response discloses threadToken, either in JSON or a
leading SSE thread event. Default widget requests store and echo it for chat, history,
mutations and feedback. An org-wide widget token does not grant access to another visitor’s
thread. For this server, STATESET_THREAD_TOKEN_REQUIRED=true also rejects legacy threads
that never had capabilities; it does not recover missing capabilities. The separate hosted
ResponseCX service uses its own enforcement settings.
A browser storage failure falls back to memory for the current page. It does not authorize a
later page load that lost a protected conversation’s token. Custom buildThreadRequest
overrides own the full request and must supply required headers.
Preserve message identity on retries
The current widget creates a stableclientMessageId for a send and reuses it on recovery.
With a session ID (or thread-token header as the execution scope), the server caches completed
logical replies for ten minutes, subject to a 256 KiB captured-response limit. JSON and completed SSE can replay with
X-Idempotent-Replay: true, without executing the action again. Cached access to an existing
thread is reauthorized; a session ID alone is not a capability. Oversized or incomplete replies
are not reusable cached successes, even if an external action already happened.
For a custom client, preserve both IDs for the same intentional send:
A failed stream is not proof that a commerce action failed. Use Check for a reply to refresh
without resending. To inspect the authorized thread directly, populate these environment
variables from the same visitor session and issue a read:
A timeout or interrupted connection does not prove that the server or a commerce provider
rejected the action. Preserve its identity and reconcile the stored result first.
data: [DONE] event and no error events. A quoted
marker, a comment or an unfinished frame cannot establish completion. The UI may accept a
custom stream’s natural end; that does not make an incomplete server execution replayable.
Timeouts and conversation changes
Current browser limits cover response bodies as well as connection setup:
Partial output remains marked interrupted. Starting or selecting another conversation,
forgetting it, or deleting the current thread cancels obsolete reads and sends so late replies
cannot restore the discarded transcript. Failed deletion preserves the transcript and capability.
Browser privacy and retention
Setsettings.security.retentionDays to expire inactive browser transcripts before restoring
them. Omit it to retain existing behavior, or use 0 to disable transcript and capability
persistence. settings.session.persistThreadTokens: false keeps capabilities in memory.
Session storage can be selected through sessionConfig.storage or the session settings alias.
Forget this conversation on this device clears its local transcript, saved session and
capability. It does not erase server reporting, Redis state, helpdesk tickets or backups.
Thread deletion and those systems’ retention policies are separate operations. Persisted
attachment labels do not contain file bytes or temporary preview URLs.