Before you start
Three things must be true, and all three are on PolyAI’s side.
The integrator needs: a key ID and a secret from PolyAI, a backend endpoint that can sign a JWT, and a few lines of JavaScript on the page.
Step 1 - Register the callback
onContextRequired takes a handler receiving { sessionId, contextId } and returning a signed JWT string, or a promise of one.
onReady is comfortably in time. The effective deadline is SESSION_START.
Other behaviours worth knowing:
- One handler slot, not a list. Registering twice silently overwrites - last call wins, no warning. There is no way to unregister;
WebchatAPI.off()does not apply here. destroy()clears the handler. Re-initialising the widget means re-registering.contextIdcan beundefined. The SDK reads it defensively off the payload. Signingsub = undefinedwill fail the vault’s binding check - guard for it.- A synchronous throw is caught. The handler is invoked inside a promise chain, so a raw
throwbecomes a decline rather than stranding the widget.
Step 2 - Sign the token on your backend
HS256, signed with the project’s key. Never in the browser.Token contract
The token is signed, not encrypted -
ctx is readable by anyone who sees the token. It proves origin, not confidentiality.
Step 3 - Refresh mid-conversation
The timing budget
Three timeouts interact, and the tightest one is the one that matters.Failure behaviour
Verified context is best-effort and fails open. The conversation always starts.No success or failure signal ever reaches the host page. There is no
onContextSet / onContextFailedcallback — the full context-related public surface is onContextRequired and refreshVerifiedContext. If the vault rejects your token, the widget logs it, resolves internally as failed, and the agent joins without context. Your page is not told. Budget for widget-console and network-tab debugging, and design the agent to degrade gracefully.Related pages
Verified Context Injection
What Verified Context Injection is, when to use it, and how it works end to end.

