Identify users
By default, the widget treats every visitor as anonymous. Call identify to
tell UserJot who the current user is. Their feedback, votes, and messages are
then tied to their account.
Basic identification
uj.identify({
user: {
id: 'user-123',
email: 'ada@example.com',
firstName: 'Ada',
lastName: 'Lovelace',
avatar: 'https://example.com/avatar.jpg'
}
});user.id is required. Use a stable ID from your own system, like your database
user ID. Do not use values that can change, like an email address or a display
name.
Everything else is optional, but email is strongly recommended. It makes the
identity easier to reconcile across UserJot surfaces.
When to call identify
Call identify once your app knows who the user is, usually right after your
session loads. Calling it again with the exact same input is safe; the SDK
skips the duplicate call as long as that session is still live. Once the
session expires, the same input triggers a fresh call. Changing anything in
the payload, including traits or email, always sends a fresh call, and a
different user switches the session to that user.
When the user logs out of your app, call logout:
uj.logout();A typical pattern:
if (user) {
uj.identify({
user: {
id: user.id,
email: user.email,
firstName: user.firstName,
lastName: user.lastName
}
});
} else {
uj.logout();
}Adding traits
Traits are custom attributes you attach to a user. They show up alongside the user in your dashboard and help you understand who is asking for what.
uj.identify({
user: {
id: 'user-123',
email: 'ada@example.com',
traits: {
plan: 'pro',
seats: 12,
trialing: false
}
}
});Trait values can be strings, numbers, booleans, or null.
Adding companies
If your product is B2B, you can attach the user's companies:
uj.identify({
user: { id: 'user-123', email: 'ada@example.com' },
companies: [
{
id: 'acme',
name: 'ACME Inc.',
domain: 'acme.com',
traits: { plan: 'enterprise' }
}
]
});id is required for each company. Use a stable ID from your own system.
What identify returns
identify returns a promise with the result:
const result = await uj.identify({
user: { id: 'user-123', email: 'ada@example.com' }
});
result.viewer; // the identified user, or null
result.identityTrust; // 'signed' or 'unsigned'
result.warnings; // anything the server ignored or adjustedCheck warnings during development. For example, if you send a field the
server does not support, the warning tells you which one.
Identity and conversations
If Conversations is enabled, identity changes how the Messages surface behaves:
- Identified users skip the visitor-details prompt entirely. Replies from your team reach them at their account email.
- Anonymous visitors get guest conversations scoped to their browser, with optional contact capture depending on your widget settings.
One subtlety: if your workspace requires signed tokens, an unsigned identify
does not work at all. The server rejects it with HTTP 403, the promise rejects
with an IDENTIFY_FAILED error, and nothing from the call is applied — the
visitor stays anonymous, with no prefilled contact details. Use
signed identity to attach conversations to
verified accounts.
Verified identity
A plain identify call is unsigned. It comes from the browser, so it can be
tampered with. That is fine for many products, but if you want UserJot to trust
the identity, or you want to require it, have your server sign the identity as
a JWT.
That is covered in Signed identity.