Scalar DevelopersScalar Developers
User Guide
API Reference
FAQs
User Guide
API Reference
FAQs
  • Getting started

    • User Guide
    • Getting Started
  • Scalar Script

    • Installing the Script
    • Identifying Users
  • Managing content

    • Managing Ideas
    • Managing Announcements
    • Managing Surveys
  • Configuration

    • Team Management
    • Customising Topics
    • User Segments
    • Subscription Plans
  • API integrations

    • Generating API Keys
    • Setting Up Webhooks
    • Syncing Customers
    • Submitting Feedback

Identifying users

Identify users in the Scalar widget to personalise surveys, segment responses, and track feedback by customer.


Basic identification

Call ScalarWidget.identify() after the script loads to link the current visitor to a user in your system:

ScalarWidget.identify({
    email: '[email protected]',
    name: 'Jane Smith',
    session_proof: '{{ server_generated_proof }}',
    expiry: {{ unix_timestamp }}
});

Requirements:

  • email is required and must be a valid email address
  • name is optional but recommended
  • session_proof is required for identity verification (see identity verification below)
  • expiry is required; a Unix timestamp for when the proof expires

The identity persists in the browser's local storage. Users remain identified until you call unidentify() or they clear their browser data.


Identity verification

Identity verification prevents users from spoofing each other's identities. It uses HMAC-SHA256 signatures generated on your server.

How it works

  1. The widget returns a session object with session_id
  2. Send session_id and user details to your server
  3. Server computes HMAC-SHA256 using the Widget Signing Secret and returns the proof
  4. Call ScalarWidget.identify() with the returned proof

Generating the session proof

The proof is an HMAC-SHA256 hash of session_id:company_slug:expiry using your signing secret.

Note: The session_id comes from the widget initialisation on the client. You must pass it to your backend to generate the proof.

Python:

import hashlib
import hmac
import time

signing_secret = 'your_widget_signing_secret'
session_id = request.json.get('session_id')  # sent from client
company_slug = 'your-company-slug'
expiry = int(time.time()) + 3600      # valid for 1 hour

message = f'{session_id}:{company_slug}:{expiry}'
session_proof = hmac.new(
    signing_secret.encode(),
    message.encode(),
    hashlib.sha256
).hexdigest()

Node.js:

const crypto = require('crypto');

const signingSecret = 'your_widget_signing_secret';
const sessionId = req.sessionId;       // from the widget session
const companySlug = 'your-company-slug';
const expiry = Math.floor(Date.now() / 1000) + 3600;  // valid for 1 hour

const message = `${sessionId}:${companySlug}:${expiry}`;
const sessionProof = crypto
    .createHmac('sha256', signingSecret)
    .update(message)
    .digest('hex');

Ruby:

require 'openssl'

signing_secret = 'your_widget_signing_secret'
session_id = session[:widget_session_id]
company_slug = 'your-company-slug'
expiry = Time.now.to_i + 3600

message = "#{session_id}:#{company_slug}:#{expiry}"
session_proof = OpenSSL::HMAC.hexdigest('sha256', signing_secret, message)

PHP:

$signingSecret = 'your_widget_signing_secret';
$sessionId = $_SESSION['widget_session_id'];
$companySlug = 'your-company-slug';
$expiry = time() + 3600;

$message = "{$sessionId}:{$companySlug}:{$expiry}";
$sessionProof = hash_hmac('sha256', $message, $signingSecret);

Passing the proof to the widget

Render the proof and expiry server-side into your page template, then pass them to ScalarWidget.identify():

<script>
    ScalarWidget.ready(function() {
        ScalarWidget.identify({
            email: '{{ current_user.email }}',
            name: '{{ current_user.name }}',
            session_proof: '{{ session_proof }}',
            expiry: {{ expiry }}
        });
    });
</script>

Important: Never expose your Widget Signing Secret in client-side code. Always generate the proof on your server. Additionally, validate the freshness of the request using an expiry timestamp to prevent replay attacks.


Waiting for the widget to load

If you need to identify users immediately after the script loads, use the ready() callback:

ScalarWidget.ready(function() {
    ScalarWidget.identify({
        email: '[email protected]',
        name: 'Jane Smith',
        session_proof: '{{ server_generated_proof }}',
        expiry: {{ unix_timestamp }}
    });
});

Custom attributes

Pass custom attributes to segment users in surveys. Use attributes for user properties like plan type, account age, or any data relevant to your surveys:

ScalarWidget.identify({
    email: '[email protected]',
    name: 'Jane Smith',
    session_proof: '{{ server_generated_proof }}',
    expiry: {{ unix_timestamp }},
    attributes: {
        plan: 'premium',
        mrr: 99,
        signup_date: '2024-01-15',
        is_trial: false
    }
});

Attribute values can be strings, numbers, or booleans.


Company association

Link users to their company for B2B segmentation:

ScalarWidget.identify({
    email: '[email protected]',
    name: 'Jane Smith',
    session_proof: '{{ server_generated_proof }}',
    expiry: {{ unix_timestamp }},
    companies: [
        { id: 'acme-corp', name: 'Acme Corporation' }
    ]
});

Each company object requires:

  • id - A unique identifier for the company
  • name - Display name for the company

Clearing identity on logout

Call unidentify() when users log out to clear their identity:

ScalarWidget.unidentify({
    session_proof: '{{ server_generated_proof }}',
    expiry: {{ unix_timestamp }}
});

This removes the stored identity and notifies the widget to treat subsequent responses as anonymous.


Full example

Here's a complete example that identifies users after login:

<!-- Scalar Surveys Widget -->
<script
    src="https://your-workspace.scalar.co.za/widget-loader.js"
    data-company="your-company"
    async
></script>
<script>
    // Wait for widget to load
    ScalarWidget.ready(function() {
        // Check if user is logged in (your app's logic)
        if (window.currentUser) {
            ScalarWidget.identify({
                email: window.currentUser.email,
                name: window.currentUser.name,
                session_proof: window.currentUser.sessionProof,
                expiry: window.currentUser.proofExpiry,
                attributes: {
                    plan: window.currentUser.plan,
                    created_at: window.currentUser.createdAt
                }
            });
        }
    });
    
    // Call on logout
    function handleLogout() {
        ScalarWidget.unidentify({
            session_proof: window.currentUser.sessionProof,
            expiry: window.currentUser.proofExpiry
        });
        // ... your logout logic
    }
</script>

API reference

ScalarWidget.identify(options)

Identify the current user.

ParameterTypeRequiredDescription
emailstringYesUser's email address
namestringNoUser's display name
session_proofstringYesHMAC-SHA256 proof generated on your server
expirynumberYesUnix timestamp for when the proof expires
attributesobjectNoCustom attributes for segmentation
companiesarrayNoCompanies the user belongs to

Returns a Promise that resolves when identification is complete.

ScalarWidget.unidentify(options)

Clear the current user's identity.

ParameterTypeRequiredDescription
session_proofstringYesHMAC-SHA256 proof generated on your server
expirynumberYesUnix timestamp for when the proof expires

Returns a Promise that resolves when the identity is cleared.

ScalarWidget.ready(callback)

Register a callback to run when the widget is ready.

ParameterTypeRequiredDescription
callbackfunctionYesFunction to call when ready

ScalarWidget.getUser()

Get the current identified user.

Returns the user object or null if no user is identified.


Next steps

  • Installing the script - First setup
  • Managing surveys - Create and configure surveys
Last Updated: 19/02/2026, 05:48
Contributors: Tlotlego Mogapi
Prev
Installing the Script