Website SDK
Identity verification
Sign your logged-in users into the chat with a JWT, so the agent knows who they are and actions can act on their account.
If your customers log in to your website or app, pass a signed token to the chat. The customer is then verified: their contact is created or updated with your user ID, email, name, phone and attributes; the AI can personalise answers; actions limited to verified customers can run; and they see their earlier chats on every device.
1. Get the secret
Open Build → Actions → Verified customers and click Create secret. Keep it on your server — never in your website's code. Create new secret replaces it (old tokens stop working).
2. Sign a token on your server
A JWT signed with HS256 using the secret. Supported claims:
| Claim | Type | Notes |
|---|---|---|
user_id (or sub) | string | Your user ID — becomes the contact's external_id |
email | string | |
name | string | |
phone | string | With country code |
attributes | object | Custom attributes, e.g. { "plan": "Pro", "orders": 7 } |
exp | number | Required. Unix time, at most 30 days ahead — an hour is plenty |
nbf | number | Optional "not before" |
// npm i jsonwebtoken
const jwt = require("jsonwebtoken");
const token = jwt.sign(
{ user_id: user.id, email: user.email, name: user.name, attributes: { plan: user.plan } },
process.env.ANYTIMEREPLY_IDENTITY_SECRET,
{ algorithm: "HS256", expiresIn: "1h" }
);3. Give it to the chat
<script>
window.AnytimeReplySettings = { user: { token: "<?= $token ?>" } };
</script>
<script src="https://anytimereply.com/widget.js" data-agent="YOUR_AGENT_KEY" defer></script>Single-page app? Call AnytimeReply.identify({ token }) after the user signs in, before they open the chat.
What is rejected
Tokens are ignored (the visitor simply chats as a guest) when the signature is wrong, the algorithm isn't HS256, exp is missing, in the past or more than 30 days ahead, or nbf is in the future.
Older method: signed email
Instead of a JWT you can sign only the email: hash = hex HMAC-SHA256 of the lower-cased, trimmed email with the same secret. It verifies the email but doesn't fill contact attributes.
const crypto = require("crypto");
const hash = crypto.createHmac("sha256", process.env.ANYTIMEREPLY_IDENTITY_SECRET)
.update(user.email.trim().toLowerCase()).digest("hex");
// window.AnytimeReplySettings = { user: { email: user.email, name: user.name, hash } };From your backend instead
Using the REST API? Pass verified_email with POST /api/v1/chat — your API key already proves the request comes from you.