Skip to content

User Identification

Open in workspace →

User identification lets you associate messenger conversations with known users in your application.

For visitors who aren’t logged in, set the user to anonymous:

optlo.setUser({ id: null });

Anonymous sessions are tracked via browser cookies.

Pass user data directly when JWT verification is not required:

optlo.setUser({
id: "user-123",
email: "jane@example.com",
name: "Jane Doe",
avatarUrl: "https://example.com/avatar.jpg",
attrs: {
plan: "pro",
active: true,
},
organizations: [{ id: "org-456", name: "Acme Corp", attrs: { industry: "SaaS" } }],
});
Field Type Required Description
id string | number | null yes Unique user ID, or null for anonymous
email string no Email address
name string no Display name
avatarUrl string no Profile image URL (must be https://)
attrs object no Custom key-value pairs (max 50)
organizations array no Organizations the user belongs to (max 10)

User and organization data appears in the user details panel in the inbox.

Each entry in the organizations array accepts the following fields:

Field Type Required Description
id string | number yes Unique organization identifier
name string yes Organization display name
attrs object no Custom key-value pairs (max 50)

Organizations are deduplicated by their id. A user can belong to up to 10 organizations.

The organizations array is always treated as the complete list. If you previously included an organization and omit it in a subsequent setUser() call, the user will be removed from that organization.

Identity verification uses asymmetric cryptography — you sign user data on your server and we verify it on ours. This ensures user identity can’t be faked from the browser. See Settings > Messenger > Install for a full walkthrough.

optlo.setUser({ jwt: "eyJ..." });
  1. Generate an asymmetric key pair using one of the supported algorithms: EdDSA, ES256, PS256, or RS256. You can use openssl to generate a key pair:

    Terminal window
    openssl genpkey -algorithm ed25519 -out private.pem
    openssl pkey -in private.pem -pubout -out public.pem
  2. Upload the public key (SPKI format) in the dashboard.

  3. Sign a JWT on your server with the private key:

    import { SignJWT } from "jose";
    let jwt = await new SignJWT({
    id: "user-123",
    email: "jane@example.com",
    name: "Jane Doe",
    })
    .setProtectedHeader({ alg: "EdDSA" })
    .setExpirationTime("5m")
    .sign(privateKey);
  4. Pass the signed JWT to the widget from your frontend.

The JWT payload uses the same user data fields as the unsigned setUser call. The exp claim is required. You can optionally include a jti claim for one-time-use token enforcement.

When replacing a public key, the previous key remains valid for 2 hours to prevent disruption.