Skip to main content
User verification lets you link chat conversations to authenticated users in your application. When a visitor is logged in on your site, you can pass their identity to ReplyBubble so their conversations are attributed to a real user — not an anonymous visitor.
Plan requirement: User verification is available on Pro and Enterprise plans.

Why use it?

  • See who’s chatting. Conversations show the user’s name, email, and company instead of “Visitor #a3f21.”
  • Filter by identified users. The dashboard lets you toggle “Identified users only” to focus on conversations from known users.
  • Skip contact forms. Verified users don’t see the contact capture form — their info is already known.
  • Prevent impersonation. HMAC signatures prove the user is actually authenticated on your server, not just claiming to be someone.

How it works

  1. Your server generates an HMAC-SHA256 signature using your secret key and the user’s ID.
  2. Your frontend passes that signature (along with user details) to the widget.
  3. ReplyBubble verifies the signature against your secret.
  4. If valid, the conversation is linked to a verified contact.
Your Server                     Browser                      ReplyBubble
    |                              |                              |
    |-- signature = HMAC(userId) ->|                              |
    |                              |-- identify({ id, signature })|
    |                              |                              |-- verify HMAC
    |                              |                              |-- link contact
    |                              |<---- { verified: true } -----|

Setup

Step 1: Generate a secret

  1. Go to Dashboard > Integrations > User Verification.
  2. Click Generate Secret.
  3. Copy the secret immediately — it is shown once and cannot be retrieved later.
  4. Store it securely on your server (environment variable, secrets manager, etc.).

Step 2: Choose a verification mode

In the same panel, set the Verification Mode:
ModeBehavior
OffIdentity verification is disabled. identify() calls return { status: "disabled" }.
OptionalSigned calls are verified and linked. Unsigned calls return prefill data (name, email pre-populate forms) but don’t create verified contacts.
RequiredOnly signed calls are accepted. Unsigned or incorrectly signed calls are rejected with a 403 error. The widget cannot send messages without a valid signature.
Recommendation: Start with Optional while integrating. Switch to Required once your server-side signing is deployed and tested.

Step 3: Sign on your server

Generate an HMAC-SHA256 signature of the user’s ID using your secret. Only the user ID is signed — not the email, name, or other fields.
const crypto = require('crypto');

function generateReplyBubbleSignature(userId, secret) {
  return crypto
    .createHmac('sha256', secret)
    .update(userId)
    .digest('hex');
}

// Example
const signature = generateReplyBubbleSignature('user-123', process.env.REPLYBUBBLE_SECRET);
Pass the signature to your frontend — for example, by embedding it in the page template or returning it from an API endpoint.

Step 4: Call identify() in the browser

After the widget loads and the user is logged in, call identify() with the user’s details and the server-generated signature:
window.ReplyBubble.identify({
  id: 'user-123',              // required -- must match what was signed
  signature: 'a1b2c3d4...',   // required for verification -- from your server
  email: '[email protected]',   // optional
  name: 'Jane Doe',            // optional
  company: 'Acme Inc',         // optional
  phone: '+1-555-0123',        // optional
  traits: {                    // optional -- up to 20 custom key-value pairs
    plan: 'enterprise',
    role: 'admin'
  }
});
Or pass user data at init time via data attributes:
<script src="https://app.replybubble.com/widget/replybubble.js"
        data-widget-id="YOUR_WIDGET_ID"
        data-user-id="user-123"
        data-user-email="[email protected]"
        data-user-name="Jane Doe"
        data-user-signature="a1b2c3d4..."
        async>
</script>

Step 5: Reset on logout

When a user logs out of your application, call reset() to clear their identity and start a fresh conversation:
window.ReplyBubble.reset();

What gets verified?

Only the id field is cryptographically verified via HMAC. The other fields (email, name, company, phone, traits) are accepted as-is from your application. This matches the industry standard used by Intercom, Drift, and similar tools. Why? Your server already authenticated the user. The HMAC proves the identify() call came from your server (not a browser console). The additional fields are trusted because they originate from your application’s authenticated context.

Dashboard features

Once users are identified, you get additional capabilities in the dashboard:
  • Verified badge — Conversations from verified users show a green “Verified” shield badge.
  • Contact linking — Verified users are automatically linked to a contact record with their name, email, and company.
  • Identified filter — Toggle “Identified users only” on the Conversations page to focus on known users.
  • Identified rate metric — The dashboard home page shows what percentage of conversations come from identified users.

Edge cases

User switches accounts

If a user logs out and logs in as a different user, call reset() first, then identify() with the new user’s details. Each conversation is linked to a single user — ReplyBubble will not overwrite a conversation already claimed by a different user.

Widget loaded before user authenticates

Call identify() at any time after init(). The widget works for anonymous visitors and links the conversation when identify() is called later in the session.

Regenerating the secret

If your secret is compromised, click Regenerate Secret in the dashboard. The old secret is immediately invalidated. Update your server with the new secret. Users with in-flight sessions using the old signature will need to refresh to get a new one.

Troubleshooting

SymptomCauseFix
identify() returns { status: "disabled" }Verification mode is set to “Off”Change mode to “Optional” or “Required” in the dashboard
identify() returns 403Mode is “Required” and the signature is missing or invalidCheck that your server is signing with the correct secret and passing only the user ID
identify() returns { verified: false, prefill: {...} }Mode is “Optional” and the signature is missing or invalidPass a valid signature from your server, or keep using Optional mode for gradual rollout
Conversation shows as anonymous despite identify()identify() was called before init()Ensure the widget is initialized first, then call identify()
402 errorFree planUpgrade to Pro or Enterprise

API reference

window.ReplyBubble.identify(user)

FieldTypeRequiredDescription
idstringYesUnique user ID in your system (max 512 chars)
signaturestringFor verificationHMAC-SHA256 hex digest of id using your secret
emailstringNoUser’s email address
namestringNoDisplay name (max 200 chars)
companystringNoCompany name (max 200 chars)
phonestringNoPhone number (max 50 chars)
traitsobjectNoCustom key-value pairs (max 20 keys, values: string/number/boolean)

window.ReplyBubble.reset()

Clears the current identity and starts a fresh conversation. Call this when the user logs out.