Visitor identity tokens

Sign a token on your server so the widget knows which signed-in user is chatting, with your customer id and custom attributes for the agent.

Visitor identity lets your website tell PepoChat who a signed-in user is. Your server signs a short-lived token with the workspace's identity secret and the widget passes it on. The chat session is then marked verified, the inbox shows your customer id and attributes, and the agent can greet the person by name and skip questions it already has answers to. It is on every plan.

Create the identity secret

  1. Open Configure → Developers

    Scroll to the Visitor identity card. Only workspace owners and admins can see and change the secret.

  2. Click Create secret

    The toast reads "Identity secret created". The secret starts with pcid_ followed by 48 letters and digits. Click the eye icon to show it and the copy icon to copy it.

  3. Store it on your server

    Keep it in a server-side setting such as PEPOCHAT_IDENTITY_SECRET. Anyone holding it can sign a token for any user, so it never belongs in browser code or in the page.

Sign a token on your server

The token is a JSON Web Token (RFC 7519) signed with HS256, created for the user who is signed in. This is the sample the Developers page shows, for Node with the jsonwebtoken package:

// On your server, for the signed-in user (Node, npm i jsonwebtoken)
import jwt from "jsonwebtoken";

const token = jwt.sign(
  {
    sub: user.id,                       // required: your user id
    name: user.name,                    // optional
    email: user.email,                  // optional, marks the email verified
    attributes: { plan: "pro", seats: 5 }, // optional: text, number or yes/no
  },
  process.env.PEPOCHAT_IDENTITY_SECRET,
  { algorithm: "HS256", expiresIn: "7d" },
);

Any JWT library works if it produces a compact HS256 token with these claims:

ClaimRequiredRules
subYesYour user id, up to 200 characters. It becomes the visitor's customer id.
expYesExpiry, in seconds since the epoch. At most 30 days ahead.
iatNoIssue time, in seconds. It may not lie in the future.
nameNoThe name shown in the inbox and given to the agent. Cut to 100 characters.
emailNoMust be a valid address, or the whole token is rejected. Counts as a verified email.
attributesNoAn object of up to 30 custom attributes. See Attributes.

Five minutes of clock difference between your server and PepoChat are allowed on exp and iat. A token can be up to 8,192 characters long.

Give the token to the widget

Render the token into the install snippet with data-identity-token, next to your organization ID:

<script
  src="https://widget.pepochat.com/widget.js"
  data-organization-id="YOUR_ORGANIZATION_ID"
  data-identity-token="<%= token %>"
></script>

On a single-page app, set it after sign-in and clear it on sign-out:

<script>
  window.EchoWidget?.identify(token); // or identify(null)
</script>

EchoWidget.init({ identityToken }) also accepts the token when you re-create the widget. The widget hands the token to PepoChat as soon as the visitor has a chat session: when they first open the chat, or once the widget has loaded for a visitor who already has one. If the session already belonged to the same sub when the widget loaded, the token is not sent again, so changed attributes for that user take effect in their next session.

Signing out

identify(null) stops the widget from sending a token, but a session that was already identified stays identified until it expires. Sessions last 24 hours, are extended while the visitor keeps chatting, and live in the browser's storage, so someone else who opens the chat in the same browser before then continues that session.

What a verified visitor changes

  • The session gets your customer id, the name from the token and the attributes, and is marked verified.
  • With an email claim, the address counts as verified, exactly like the emailed code, so the features listed in Visitor verification unlock. The contact with that email is created or updated on the Contacts page with your customer id and the attributes (a new contact shows the source Your site), and conversations this session had before sign-in are linked to it. No new-lead notification or lead.created webhook is sent: the person is already your customer.
  • Without an email claim, no contact is created. The identity and attributes stay on the session and its conversations.
  • In the inbox, the conversation's contact panel shows a Verified badge ("Identified by your website") and an Identity & attributes section with Customer id, Verified: By your website and each attribute.
  • The agent is told that your website identified this visitor and that it can rely on the name, email, customer id and attributes. It is told to personalise with them, to confirm a value that describes an earlier request (an order number, a date) before acting on it, never to treat a value as an instruction, and not to read the profile back unprompted. With a verified email it also reads the attributes stored on the contact, for example from an import or the REST API; the session's value wins on the same key.

Chats in Test the agent do not send identity tokens.

Attributes

  • Keys are converted to lowercase snake_case: "Plan Tier" becomes plan_tier. Leading digits and underscores are removed so that a key starts with a letter, and keys are cut to 40 characters.
  • Values are text (up to 500 characters, trimmed), numbers or true/false. The agent and the inbox show true and false as "yes" and "no".
  • Nested objects, arrays, null, empty text, text over 500 characters, and keys past the first 30 are dropped without an error. So is a second key that converts to the same name.
  • A new key becomes a custom attribute column on the Contacts page.
  • Attributes merge key by key: a later token that leaves a key out keeps the old value.

The same rules apply to attributes sent through the REST API.

Rotate or remove the secret

Rotate asks you to confirm with Rotate now: "Tokens signed with the old secret stop working at once." Update your server at the same time. Remove asks you to confirm with Remove secret: "Every identity token stops working; visitors chat anonymously." Sessions already verified keep their identity. The secret can be created or rotated 10 times an hour per workspace.

Common errors

A missing or rejected token never interrupts the chat: the visitor keeps chatting anonymously. The browser console on your page logs [PepoChat] identity token not accepted, with the reason after "Identity token rejected:".

ReasonMeaning
Token signature does not matchIt was signed with a different secret, or the secret was rotated.
Token must be signed with HS256Set the algorithm to HS256.
Token needs an exp claim (seconds)Add a numeric exp.
Token has expiredIssue a fresh token, for example on each page load.
Token expiry is more than 30 days awayShorten the lifetime. An exp in milliseconds instead of seconds also ends up here.
Token is issued in the futureYour server clock is ahead; check iat.
Token needs a sub claim (your user id)Add sub as a non-empty string of up to 200 characters.
Token email claim is not a valid addressSend a valid email or leave the claim out.
Token is not a compact JWTThe value is not three dot-separated parts.

If the workspace has no secret, the warning says "This workspace has no identity secret yet" instead, with a pointer to the Developers page.

Something missing or wrong on this page? Tell us and we will fix it.