SupportWhale
← All help articles
Getting started

Connect signed-in customers

Securely send names, email addresses and customer context to the chat widget with signed JWTs.

Last updated · Nov 2, 2026

Why connect customer identity?

For websites with customer accounts, verified identity lets SupportWhale show the correct conversation history and include names, email addresses and additional context in the inbox. This does not enable optional returning-visitor recognition or email-opening measurement.

1. Create the signing secret

Open Settings → Installation → Verified customers and create an identity secret. Store the displayed secret immediately in your own backend environment, for example as SUPPORTWHALE_IDENTITY_SECRET. It is shown only once. Creating a new secret replaces the old one and invalidates existing signed tokens. Never put it in browser code or the widget snippet.

2. Sign the token on your server

Create an endpoint on your backend, for example /your-backend/support-identity, accessible only to signed-in customers. Read the account from your authenticated server session, not a user ID supplied by the browser. This example uses Web Crypto on the server (Node.js 22+, Deno, Bun or Workers). Replace sw_YOUR_WEBSITE_KEY with your public website key from Installation:

// Server only: Web Crypto (Node.js 22+, Deno, Bun, Workers).
// user must come from your authenticated session, never request input.
// identitySecret is the exact secret text from server configuration.
async function createIdentityToken(user, identitySecret) {
  const encode = (value) => btoa(String.fromCharCode(...value))
    .replace(/=/g, '').replace(/\+/g, '-').replace(/\//g, '_');
  const utf8 = new TextEncoder();
  const now = Math.floor(Date.now() / 1000);
  const header = encode(utf8.encode(JSON.stringify({ alg: 'HS256', typ: 'JWT' })));
  const payload = encode(utf8.encode(JSON.stringify({
    sub: String(user.id), iss: "sw_YOUR_WEBSITE_KEY", aud: 'supportwhale',
    iat: now, exp: now + 300, name: user.name, email: user.email,
    metadata: { plan: user.plan }
  })));
  const key = await crypto.subtle.importKey(
    'raw', utf8.encode(identitySecret), { name: 'HMAC', hash: 'SHA-256' }, false, ['sign']
  );
  const signature = await crypto.subtle.sign('HMAC', key, utf8.encode(header + '.' + payload));
  return header + '.' + payload + '.' + encode(new Uint8Array(signature));
}

Return { "token": "..." } with Cache-Control: no-store from your endpoint and HTTP 401 if the customer is signed out. Use your secret from server configuration. Required JWT claims are sub (stable, nonempty customer ID, at most 200 characters), iss (public website key), aud (supportwhale), iat and exp (Unix seconds, no longer than five minutes). Optional: name, email, avatar and JSON metadata (up to about 5 KB). A plan name is useful context; never include passwords or other secrets. Copyable TypeScript, PHP, C# and Ruby examples are also available under Settings → Installation → Verified customers → Integration example.

3. Connect the user in the browser

Register a provider that requests a fresh short-lived token from your backend each time. SupportWhale renews verified sessions automatically and keeps the right conversation history:

// Run on your site for an authenticated customer.
function connectSupportWhaleUser() {
  void window.SupportWhale.setIdentityProvider(async () => {
    const response = await fetch('/your-backend/support-identity', {
      credentials: 'same-origin', cache: 'no-store'
    });
    if (!response.ok) throw new Error('Sign-in required');
    const { token } = await response.json();
    return token;
  });
}
if (window.SupportWhale && !window.SupportWhale._queue) {
  connectSupportWhaleUser();
} else {
  window.addEventListener('supportwhale:ready', connectSupportWhaleUser, { once: true });
}

4. Sign out and test

Call await window.SupportWhale.reset() on logout or account change before connecting another account. This clears the prior user's local chat session. Register the provider again for the new account. Failed renewal never silently starts anonymous chat. Test with two accounts to verify conversation isolation.

Connecting signed-in customers is distinct from recognizing anonymous website visitors. Optional measurements and consent.

Need a hand? Contact us →