Skip to main content
The Permutive SDK provides identity management to track users across sessions and connect data from multiple devices or touchpoints.

Overview

A user on a device is automatically allocated a unique device ID by the Permutive SDK on behalf of the publisher. This user ID is distinct across publishers, such that the same user who visits two different publishers' sites on their device will be assigned distinct IDs. As a first-party identity, it does not track users across domains or devices, and it has no reliance on third-party identifiers like cookies or mobile device IDs. The user ID is used in Permutive's cloud to generate accurate publisher-level audience insights, and on-device to store cohort information across sessions.It is also possible to assign users to other IDs, called identifiers, such as an email address the user has authenticated with on the publisher's site, or a third-party identity provided by a partner that the publisher has obtained user consent for. Identifiers can be used to unify the view of a user across multiple devices they use (such as segmenting a user based on their behavior on two different sites owned by the publisher which they are logged in to) or to connect auxiliary data about the user (such as augmenting the segmentation of users with a third-party audience that a partner provides information about).

User ID

Every user is automatically assigned a unique user ID by the SDK. This ID:
  • Is generated on first visit and persisted in a first-party cookie
  • Is unique to your domain (not shared across publishers)
  • Survives browser sessions and cookie clearing in most cases
  • Is used to track behavior and build cohorts
// Get the current user ID from localStorage
var userId = localStorage.getItem('permutive-id');
console.log('User ID:', userId);
The user ID is stored in localStorage with the key permutive-id. It works in all browsers, including Safari and Firefox which block third-party cookies.

Aliases

An identifier (formerly called an alias in some SDK and API references) is an alternative identity for a user. Each identifier has:
  • Tag - The type of identifier (e.g., "email_sha256", "internal_id", "aaid")
  • Identity - The actual identifier value
  • Priority - Ordering when multiple identifiers exist (lower number = higher priority)
  • Expiry - Optional expiration date/time

Setting Aliases

Use permutive.identify() to set user aliases:
// Set a single alias
permutive.identify([
  { tag: 'email_sha256', id: 'a1b2c3d4e5f6g7h8i9j0...' }
]);

// Set multiple aliases
permutive.identify([
  { tag: 'email_sha256', id: 'a1b2c3d4e5f6g7h8i9j0...' },
  { tag: 'internal_id', id: 'user_12345', priority: 1 },
  { tag: 'subscriber_id', id: 'sub_789', priority: 2 }
]);

Identity Record Structure

Each identity record has the following fields:
FieldTypeRequiredDescription
tagstringYesThe type of identifier (configured in dashboard)
idstringYesThe actual identifier value
prioritynumberNoResolution priority (lower = higher priority)
expirynumberNoExpiration timestamp (Unix milliseconds)

Setting Identity

Basic Usage

// When user logs in
function onUserLogin(user) {
  permutive.identify([
    { tag: 'email_sha256', id: hashSHA256(user.email) }
  ]);
}

With Priority

Priority determines which identifier is used for identity resolution:
  • Lower number = Higher priority (0 is the highest)
  • Identifiers are resolved in priority order
  • If the highest priority identifier resolves to a user, that identity is used
Priority 0 (Highest): Hashed email - Most reliable, persistent
Priority 1: Internal user ID - Reliable when user is logged in
Priority 2: Advertising ID - Less reliable, can be reset
Priority 3 (Lowest): Device ID - Least reliable
// Set identities with explicit priority
permutive.identify([
  { tag: 'email_sha256', id: emailHash, priority: 0 },      // Highest priority
  { tag: 'internal_id', id: 'user_12345', priority: 1 },
  { tag: 'device_id', id: 'device_abc', priority: 2 }       // Lowest priority
]);

With Expiry

Set an expiration time for temporary identities:
// Identity expires in 24 hours
var expiryTime = Date.now() + (24 * 60 * 60 * 1000);

permutive.identify([
  { tag: 'session_token', id: 'session_abc123', expiry: expiryTime }
]);

Identity Resolution

When you set an identifier:
  1. SDK sends the identifier to Permutive servers
  2. Server checks if this identifier is associated with an existing user
  3. If found, user profiles are merged
  4. SDK receives updated cohorts and state
  5. All future events are linked to the resolved identity
When you call identify():
permutive.identify([
  { tag: 'email_sha256', id: 'abc123...' }
]);
The SDK:
  1. Sends the alias to Permutive servers
  2. Server checks if this alias exists for another user
  3. If found, user profiles are merged
  4. SDK receives updated cohorts and state
  5. Future events are linked to the resolved identity

Common Identity Patterns

// Track login and set identity
function handleLogin(user) {
  // Set identity
  permutive.identify([
    { tag: 'email_sha256', id: hashSHA256(user.email) },
    { tag: 'internal_id', id: user.id }
  ]);

  // Track login event
  permutive.track('Login', {
    method: 'email',
    is_new_user: user.isNew
  });
}

Hashing Requirements

Never send plain-text PII to Permutive. Always hash email addresses and other personal identifiers before passing them to identify().

SHA-256 Hashing

Email addresses should be hashed using SHA-256:
// Using Web Crypto API (modern browsers)
async function hashSHA256(email) {
  const normalized = email.toLowerCase().trim();
  const encoder = new TextEncoder();
  const data = encoder.encode(normalized);
  const hashBuffer = await crypto.subtle.digest('SHA-256', data);
  const hashArray = Array.from(new Uint8Array(hashBuffer));
  return hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
}

// Usage
hashSHA256('[email protected]').then(function(hash) {
  permutive.identify([
    { tag: 'email_sha256', id: hash }
  ]);
});

Hashing Best Practices

  1. Normalize before hashing: Lowercase and trim whitespace
  2. Use consistent algorithm: SHA-256 is standard
  3. Hash on server if possible: Avoids exposing raw email in client code
  4. Same hash everywhere: Use identical normalization across all touchpoints

Resetting Identity

When a user logs out, reset their identity:
function handleLogout() {
  // Reset all SDK state
  permutive.reset();

  // Or just track logout without reset
  // permutive.track('Logout', {});
}
permutive.reset() clears all user data including cohorts and identity. Use it when a user explicitly logs out or requests data deletion.

Cross-Domain Identity

For tracking users across multiple domains you own:
// On domain-a.com
permutive.identify([
  { tag: 'cross_domain_id', id: 'shared_user_123' }
]);

// On domain-b.com (same identifier)
permutive.identify([
  { tag: 'cross_domain_id', id: 'shared_user_123' }
]);

// Permutive will link the user profiles
Cross-domain identity requires using the same identity tag and value across both domains. Contact your Customer Success Manager to configure cross-domain tracking.

Identity Events

Listen for identity changes:
// Listen for identity resolution events
permutive.on('SegmentEntry', function(event) {
  // User entered a new segment after identity resolution
  console.log('Entered segment:', event.properties.segment);
});

Troubleshooting

Problem: User appears as new visitor on each session.Solutions:
  • Check that cookies aren’t being blocked
  • Verify cookie domain configuration
  • Check for browser privacy settings (private mode)
  • Ensure permutive-id cookie exists in Application > Cookies
Problem: Calling identify() but user data not connected.Solutions:
  • Verify identity tags are configured in dashboard
  • Check that identity values match exactly (case-sensitive)
  • Enable debug mode to see identify requests
  • Ensure SDK is initialized before calling identify
Problem: Same person appears as multiple users.Solutions:
  • Ensure consistent identity values across touchpoints
  • Use same hashing algorithm everywhere
  • Set identity as early as possible in the session
  • Check priority settings if multiple identities conflict