Identity resolution in Usermaven: A comprehensive guide
Usermaven’s identity resolution feature connects anonymous visitor interactions with known user profiles. This provides a complete view of the customer journey—from their initial anonymous visit to their actions as a logged-in user—enabling accurate analytics and deeper insights.
This guide outlines how identity resolution works in Usermaven, implementation steps for different tracking setups, and testing procedures.
How identity resolution works
1. Anonymous identification
Cookie-based tracking (default)
When the Usermaven tracking script loads, it sets a cookie named __eventn_id_<YOUR_API_KEY>
by default. This assigns a unique Anonymous ID, tracking user interactions across sessions.
Cookieless tracking
If configured (data-privacy-policy="strict"
), Usermaven doesn’t store cookies, limiting anonymous tracking primarily to fingerprinting. To merge that anonymous session with the real user profile, you must fire the identify call in JavaScript first. If you send the first identify only from the server, the fingerprinted visit will remain un-stitched and a new profile will be created.
2. User identification
Call usermaven("id", { ...user_details... })
using JavaScript immediately after a user signs up or logs in. This links anonymous activity to a signed-up user. In case of server-side tracking, you need to fetch the anonymous ID from the browser and pass it to the identify call.
Example client-side id
call:
usermaven("id", {
id: "USER_12345",
email: "sara.doe@example.com",
created_at: "2023-01-15T09:30:00Z",
first_name: "Sara",
last_name: "Doe",
custom: {
logins_count: 5,
trial_ends_at: "2023-11-15T23:59:59Z",
preferred_language: "en-GB"
},
company: {
id: "COMP_XYZ789",
name: "Acme Innovations Inc.",
created_at: "2022-11-20T10:00:00Z",
custom: {
plan: "Enterprise Plus",
industry: "Software Technology",
employee_count: 250
}
}
});
Implementation scenarios
1. Frontend-only tracking (JS snippet)
- Setup: Include the script on all pages of your website and app.
- Identification: Call
usermaven("id", {...})
immediately after login/signup. - SPAs: It is highly recommended to use our SDKs for SPAs. If you must use the JS snippet, use
data-auto-pageview="true"
or manually callusermaven("track", "Page Viewed")
.
Result: Merges anonymous and authenticated sessions in both cookie-based and cookieless modes.
2. Hybrid tracking (frontend + backend)
Hybrid tracking allows you to connect anonymous user activity (tracked on the frontend) with identified user activity and backend events (tracked on the backend). This provides a complete view of the user journey, from their first anonymous visit to post-login actions and lifecycle events.
Core Principle: The key is to pass Usermaven’s anonymous_id
(generated by the frontend SDK) to your backend when a user identifies themselves (e.g., signs up or logs in). Your backend then includes this anonymous_id
along with your internal user_id
in the first event(s) (usually sign-up) sent to Usermaven for that identified user. This “stitches” the anonymous profile to the identified profile.
Frontend:
1. Install Usermaven’s main tracking script on your website
This script assigns a unique anonymous ID to visitors using a first-party cookie, and it automatically tracks user interactions on your website, including pageviews, clicks, and other frontend activities.
2. Retrieving and sending the Anonymous ID to the backend
To link anonymous frontend activity with backend events, you first need to retrieve the Usermaven anonymous ID that is stored in the user’s browser.
When to Retrieve: You’ll typically retrieve this ID at the point when the user is about to identify themselves or perform an action that requires backend processing where this linkage is important, such as:
- Before submitting a signup form.
- Before submitting a login form.
- When an authenticated user performs an action that triggers a backend event you want to associate with their pre-login journey.
// Helper function to get Usermaven anonymous ID
function getUsermavenAnonymousId() {
const cookie = document.cookie
.split('; ')
.find(c => c.startsWith('__eventn_id_'));
return cookie ? cookie.split('=')[1] : null;
}
// Example: sending anonymous ID to backend upon user signup
const anonId = getUsermavenAnonymousId();
fetch('/api/signup', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
email: 'user@example.com',
anonymous_id: anonId
})
});
Important: You only need to pass the anonymous ID to your backend once, typically during signup or initial identification.
Note on cross-domain tracking:
If your marketing site and app are hosted on different domains (not subdomains), Usermaven cookies won’t automatically persist between them. To track anonymous users across domains, you can enable cross-domain tracking using Usermaven’s built-in method. This works by passing the anonymous ID through URL parameters during navigation and restoring it on the destination domain. Read the cross-domain tracking setup guide here
Backend:
Send backend events to Usermaven (server-side)
Once your server receives the anonymous ID from the frontend, the very first event you send to Usermaven must be an identify call that contains both user_id
(your permanent DB ID) and anonymous_id
(forwarded from the browser). This stitches all anonymous activity to the newly created user profile.
Here’s a practical example in Node.js/Express:
/**
* Complete backend example (Node.js + Express)
* --------------------------------------------
* • Receives anonymous_id + signup data from the browser
* • Looks up or creates the user in your DB
* • Sends a stitched IDENTIFY call to Usermaven (user_id + anonymous_id + traits + context)
* • Sends a follow-up TRACK event (“User Signed Up”) without anonymous_id
* • Returns JSON response to the client
*
* Replace:
* - '@usermaven/sdk' with the actual server SDK import for your setup
* - getOrCreateUser() with real database logic
* - API key / host with your own credentials
*/
const express = require('express');
const usermaven = require('@usermaven/sdk'); // ← change to actual import
// Initialise Usermaven server SDK
usermaven.init({
apiKey: 'YOUR_USERMAVEN_API_KEY',
trackingHost: 'https://events.usermaven.com'
});
const app = express();
app.use(express.json());
// --- pseudo-DB helper (replace with real DB query) -----------------
async function getOrCreateUser(email) {
// Lookup user by email. If not found, create and return the user record.
// Must return { id, email, created_at, first_name, last_name, plan, company? }
return {
id: 'usr_abc123',
email,
created_at: new Date(),
first_name: 'Temp',
last_name: 'User',
plan: 'Free',
company: null // or { id, name, created_at, plan_name }
};
}
// -------------------------------------------------------------------
app.post('/api/signup', async (req, res) => {
const { email, anonymous_id, first_name, last_name, chosen_plan } = req.body;
if (!email || !anonymous_id) {
return res.status(400).json({ error: 'email and anonymous_id required' });
}
try {
// 1️⃣ Fetch or create the user
const user = await getOrCreateUser(email);
// 2️⃣ IDENTIFY — stitch the anonymous cookie to user_id
await usermaven.id(
{
user_id: user.id,
anonymous_id, // only on this first stitched call
email: user.email,
created_at: user.created_at.toISOString(),
first_name: first_name || user.first_name,
last_name: last_name || user.last_name,
...(user.company && {
company: {
id: user.company.id,
name: user.company.name,
created_at: user.company.created_at.toISOString(),
custom: { plan: user.company.plan_name }
}
}),
context: {
ip: req.ip,
userAgent: req.headers['user-agent'],
library: { name: 'auth-service', version: '1.0' }
}
},
true // suppress extra user_identify event in server SDK
);
// 3️⃣ TRACK — first backend event (no anonymous_id needed)
await usermaven("track", "User Signed Up", {
user_id: user.id,
plan: chosen_plan || user.plan || 'Free',
context: {
ip: req.ip,
userAgent: req.headers['user-agent'],
library: { name: 'auth-service', version: '1.0' }
}
});
res.json({ status: 'ok', user_id: user.id });
} catch (err) {
console.error('Signup handler error:', err);
if (!res.headersSent) res.status(500).json({ error: 'internal server error' });
}
});
// Start server
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => console.log(`Server listening on ${PORT}`));
Result: Complete journey—anonymous behavior from the browser, backend lifecycle events, all stitched together.
Cookieless (strict) privacy mode: how to handle anonymous sessions
- In strict cookieless mode the browser does not store a persistent
anonymous_id
. - If the backend issues the first identify call, Usermaven will create a fresh user profile and any anonymous page-views from that user remain unlinked.
Solution
-
Fire the identify call in the browser immediately after signup or login.
This converts the live session from “anonymous” to the correct user profile, so all pre-login page-views are already attached. -
Send subsequent events from your backend using only
user_id
.
Once the browser has identified the user, every later server-side identify or track call is automatically stitched to the same profile.
Sending high-quality server-side events
To ensure your server-side events are valuable and accurately attributed in Usermaven, it’s important to include essential metadata and structure your payloads clearly.
Key layers of a good server-side event
-
Envelope
Include yourapi_key
and optionally a_timestamp
(for historical backfill). -
User & Company block
Always include the user’s permanent ID. If the user isn’t identified yet, provide ananonymous_id
to associate early activity. Add useful user traits (like email, name, signup date), and optionally, company details if it’s a B2B context. -
Event block
Describe what happened usingevent_type
and optionally attach anyevent_attributes
that help analyze the event (like amount, status, method, etc.). -
Context block
Add context to improve accuracy and enrich analytics:ip
: User’s IP address.userAgent
: Browser/device string.page
: Includeurl
,referrer
,title
, andpath
if available.campaign
: UTM parameters like source, medium, campaign, term, and content.library
: Info about what system sent the event (e.g., service name and version).locale
: User’s locale such asen-US
.
Best practices
- Always include
user_id
once the user is identified. - If sending events before identification, fetch
anonymous_id
from the browser and ensure it’s passed to Usermaven later in the identify call to stitch sessions. - Use UTC ISO 8601 format or a millisecond UNIX timestamp for accurate time tracking.
- Include relevant
custom
fields under user, company, or event attributes to enrich profiles and segments. - Send events to the official Usermaven endpoint:
https://events.usermaven.com/api/v1/s2s/event?token=YOUR_API_KEY
Following these practices ensures accurate identity resolution and reliable analytics across your product and marketing data.
Testing identity resolution
- Open your site in incognito/private mode.
- Browse multiple pages anonymously.
- Sign up or log in (fires the
id
call). - Open Contacts Hub → People in Usermaven.
- Check the user’s timeline for pre-login pageviews and events.
If anonymous activity is missing:
- Ensure the script loads before user interaction.
- Confirm the
id
call includes the correct user ID and anonymous ID. - Verify cookies aren’t being blocked or deleted.
- Check if you are using cookieless mode and if so, ensure the identify call is fired in the browser.
By following this guide, you’ll implement identity resolution in a way that gives you the most complete and reliable user insights in Usermaven.