Skip to Content

Chatbot Authentication

Chatbot 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 — click the eye icon to reveal it, then copy.

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 (e.g. user ID, email)

Recommended claim:

ClaimDescription
expToken expiry — keep it short (e.g. 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, // custom claim → agent context orderId: order.id, // custom claim → agent context }, 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, # custom claim → agent context "orderId": order.id, # custom claim → agent context "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-widget agent-id="your-agent-id" contact-context-token="YOUR_JWT" ></applied-chat-widget>

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, etc.) and metadata.groups in the HTML attribute are ignored when a verified identity is active — the JWT is the sole source of identity. Other metadata keys (data, source, platform, state, etc.) are still passed through normally.

<!-- context and groups are stripped server-side when a verified identity is active; data is sent as-is --> <applied-chat-widget agent-id="your-agent-id" contact-context-token="YOUR_JWT" metadata='{"context":{"firstName":"Ignored"},"data":{"orderId":"12345"}}' ></applied-chat-widget>

Consistent claims across sites

If your chatbot is embedded on multiple sites (e.g. a marketing site and an app), 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. For example, if Site A signs a token with {firstName: "Chris"} and Site B signs with {firstName: "Christina"}, the contact record may flip between values depending on which tab re-initializes last.

Security best practices

  • Never expose your secret key in client-side code. Always generate tokens on your server.
  • Always set exp to limit the window of a compromised token.
  • Rotate your secret key immediately if it is ever exposed.
  • Use HTTPS for all pages embedding the widget.

See also

Last updated on