Documentation Index
Fetch the complete documentation index at: https://docs.replyful.com/llms.txt
Use this file to discover all available pages before exploring further.
User identification lets you securely pass user information to the chat widget. This enables personalized conversations, linking chats to your user records, and showing user context to your support team.
How it works
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Your backend │ │ Your frontend │ │ Replyful │
└────────┬────────┘ └────────┬────────┘ └────────┬────────┘
│ │ │
│ 1. Generate token │ │
│<──────────────────────│ │
│ │ │
│ 2. Return signed JWT │ │
│──────────────────────>│ │
│ │ │
│ │ 3. replyful.identify │
│ │──────────────────────>│
│ │ │
│ │ 4. Verify & link │
│ │<──────────────────────│
- Your frontend requests a token from your backend
- Your backend generates a signed JWT using your Identity Secret
- Your frontend passes the token to the widget
- Replyful verifies the token and links the conversation to the user
Get your identity secret
- Go to your Replyful dashboard
- Navigate to Settings → Security
- Copy your Identity Secret
Keep your Identity Secret secure. Never expose it in client-side code.
Generate a token on your backend
Create an API endpoint that generates a signed JWT for authenticated users.
Install the jsonwebtoken package:Create a token endpoint:import jwt from 'jsonwebtoken';
const IDENTITY_SECRET = process.env.REPLYFUL_IDENTITY_SECRET;
function generateReplyfulToken(user) {
return jwt.sign(
{
// Required
userId: user.id,
// Optional
email: user.email,
name: user.name,
// Custom properties (visible to your support team)
plan: user.subscription?.plan,
company: user.company?.name,
},
IDENTITY_SECRET,
{
expiresIn: '1h',
algorithm: 'HS256'
}
);
}
// Express example
app.get('/api/replyful-token', authenticate, (req, res) => {
const token = generateReplyfulToken(req.user);
res.json({ token });
});
Install the firebase/php-jwt package:composer require firebase/php-jwt
Create a token endpoint:<?php
use Firebase\JWT\JWT;
$identitySecret = getenv('REPLYFUL_IDENTITY_SECRET');
function generateReplyfulToken($user) {
global $identitySecret;
$payload = [
'userId' => $user->id, // Required
'email' => $user->email, // Optional
'name' => $user->name, // Optional
'plan' => $user->plan, // Custom property
'exp' => time() + 3600 // 1 hour expiration
];
return JWT::encode($payload, $identitySecret, 'HS256');
}
// API endpoint example
if ($_SERVER['REQUEST_METHOD'] === 'GET' && $_SERVER['REQUEST_URI'] === '/api/replyful-token') {
// Ensure user is authenticated
$user = getCurrentUser();
if (!$user) {
http_response_code(401);
exit;
}
header('Content-Type: application/json');
echo json_encode(['token' => generateReplyfulToken($user)]);
}
Call identify from your frontend
After a user logs in, fetch the token from your backend and pass it to the widget:
async function identifyUser() {
const response = await fetch('/api/replyful-token', {
credentials: 'include'
});
const { token } = await response.json();
replyful('identify', { token });
}
// Call after user logs in
identifyUser();
React example
import { useEffect } from 'react';
import { useUser } from './auth';
function ReplyfulIdentify() {
const { user, isAuthenticated } = useUser();
useEffect(() => {
if (!isAuthenticated) return;
async function identify() {
const res = await fetch('/api/replyful-token');
const { token } = await res.json();
window.replyful?.('identify', { token });
}
identify();
}, [isAuthenticated, user?.id]);
return null;
}
Token payload
| Field | Type | Required | Description |
|---|
userId | string | Yes | Unique identifier in your system |
email | string | No | User’s email address |
name | string | No | User’s display name |
* | any | No | Custom properties (visible to support) |
Security best practices
- Never expose your Identity Secret in client-side code
- Generate tokens server-side only to prevent tampering
- Use short expiration times (1 hour recommended)
- Authenticate users before generating tokens
- Use HTTPS for all API requests
The widget handles missing or invalid tokens gracefully — users can still chat anonymously.