Skip to Content

Chat Widget Authentication

Chat widget authentication lets you tie widget conversations to known customers using JSON Web Tokens (JWTs). When enabled, verified users see their full conversation history across sessions, and any custom claims you include in the token become available as agent context.

Prerequisites

  1. Enable Strict Authentication in Agent Settings -> Security.
  2. Copy your secret key from the same page.

1. Generate a JWT (server-side)

Sign a JWT on your backend using HS256 and your secret key. Never expose the secret key in client-side code.

Required claim:

ClaimDescription
subA stable customer identifier (for example, user ID or email)

Recommended claim:

ClaimDescription
expToken expiry — keep it short (for example, 1 hour)

Any custom claims beyond the reserved set (iat, exp, nbf, iss, aud, jti, sub) are automatically passed to the agent as conversation context.

Node.js example

const jwt = require('jsonwebtoken'); const token = jwt.sign( { sub: user.id, email: user.email, plan: user.plan, orderId: order.id, }, process.env.APPLIED_SECRET_KEY, { expiresIn: '1h' } );

Python example

import jwt import time token = jwt.encode( { "sub": user.id, "email": user.email, "plan": user.plan, "orderId": order.id, "exp": int(time.time()) + 3600, }, os.environ["APPLIED_SECRET_KEY"], algorithm="HS256", )

2. Pass the token to the widget

Set the contact-context-token HTML attribute when rendering the widget:

<applied-chat agent-id="your-agent-id" contact-context-token="YOUR_JWT" ></applied-chat>

When a user logs in or their identity changes, re-render the widget element with the new token value.

3. Logout

Call logout() to clear the session and revoke the token. The widget resets to an anonymous state.

window.applied.logout();

4. Conversation history visibility

User typeHistory
Verified (valid JWT with sub)Full history across all sessions
Anonymous (no JWT)Current session only

How metadata works with authentication

When a verified identity is active (contact-context-token JWT, Shopify proxy auth, or strict auth mode), the server strips metadata.context and metadata.groups from requests and replaces them with the verified claims from the JWT.

This means any metadata.context fields (firstName, email, and so on) and metadata.groups in the HTML attribute are ignored when a verified identity is active. Other metadata keys (data, source, platform, state, and so on) are still passed through normally.

<applied-chat agent-id="your-agent-id" contact-context-token="YOUR_JWT" metadata='{"context":{"firstName":"Ignored"},"data":{"orderId":"12345"}}' ></applied-chat>

Consistent claims across sites

If your widget is embedded on multiple sites, use the same JWT claims across all of them. Different claims on different sites can cause unexpected behavior if a user has multiple tabs open, since sessions and contacts are shared across origins.

Security best practices

  • Never expose your secret key in client-side code
  • Always set exp
  • Rotate your secret key immediately if it is ever exposed
  • Use HTTPS for all pages embedding the widget

See also

Last updated on