Link anonymous visitor data to known users. When visitors log in or submit forms, Zenovay connects their full history to their identity.
How User Identification Works
Anonymous to Known
Visitor journey:
Visit 1 (Anonymous):
Anonymous visitor browses site
→ Assigned visitor ID: viz_abc123
Visit 2 (Anonymous):
Same visitor returns
→ Same visitor ID: viz_abc123
Visit 3 (Identified):
Visitor logs in as john@acme.com
→ zenovay('identify', 'john@acme.com')
→ All history linked to john@acme.com
Future Visits:
Automatically recognized
→ Full journey preserved
Data Merged
When identified:
- Past anonymous visits linked
- Future visits tracked
- Full journey visible
- Cross-device possible
Implementing Identification
Basic Identification
Call identify when user is known:
// When user logs in
zenovay('identify', userId);
// Example
zenovay('identify', 'user_12345');
// or
zenovay('identify', 'john@acme.com');
With User Properties
Add user details:
zenovay('identify', 'user_12345', {
email: 'john@acme.com',
name: 'John Smith',
company: 'Acme Corporation',
plan: 'enterprise',
role: 'admin'
});
Supported Properties
| Property | Type | Description |
|---|---|---|
| string | Email address | |
| name | string | Full name |
| company | string | Company name |
| plan | string | Subscription tier |
| role | string | User role |
| created_at | date | Account creation |
| custom_* | any | Custom properties |
Implementation Examples
On Login
// After successful login
async function handleLogin(credentials) {
const user = await loginUser(credentials);
// Identify in Zenovay
zenovay('identify', user.id, {
email: user.email,
name: user.name,
company: user.company_name
});
// Continue with app
redirectToDashboard();
}
React Hook
import { useEffect } from 'react';
import { useAuth } from './auth';
function useZenovayIdentify() {
const { user, isAuthenticated } = useAuth();
useEffect(() => {
if (isAuthenticated && user) {
if (window.zenovay) {
window.zenovay('identify', user.id, {
email: user.email,
name: user.name,
company: user.company
});
}
}
}, [user, isAuthenticated]);
}
Form Submission
// On form submit (before login)
async function handleFormSubmit(formData) {
// Identify with email from form
zenovay('identify', formData.email, {
email: formData.email,
name: formData.name,
company: formData.company
});
// Track the form submission
zenovay('goal', 'form_submission');
// Submit to backend
await submitForm(formData);
}
Viewing Identified Users
Users Dashboard
- Go to Analytics → Users
- View identified users list
- Click user for details
User List
| User | Company | Visits | Last Seen | Score |
|---|---|---|---|---|
| john@acme.com | Acme Corp | 24 | Today | 85 |
| sarah@bigco.com | Big Co | 18 | Yesterday | 72 |
| mike@tech.io | Tech Inc | 12 | 3 days ago | 65 |
User Profile
┌─────────────────────────────────────────────────────┐
│ John Smith │
│ john@acme.com │
│ ─────────────────────────────────────────────────── │
│ │
│ Company: Acme Corporation │
│ Plan: Enterprise │
│ Role: Admin │
│ Created: November 15, 2024 │
│ │
│ ─────────────────────────────────────────────────── │
│ │
│ Analytics Summary: │
│ • Total Sessions: 24 │
│ • Total Time: 3h 45m │
│ • Pages Viewed: 89 │
│ • Goals Completed: 5 │
│ • Revenue: $4,999 │
│ │
│ First Visit: Oct 20, 2024 (anonymous) │
│ Identified: Nov 15, 2024 │
│ Last Visit: Today at 2:30 PM │
│ │
└─────────────────────────────────────────────────────┘
User Journey
Full Timeline
See complete user history:
John Smith - Journey Timeline
January 15, 2025
├── 2:30 PM - Settings page (5 min)
├── 2:00 PM - Dashboard (10 min)
└── Logged in
January 10, 2025
├── 3:45 PM - Billing page (3 min)
├── 3:40 PM - Upgrade modal → Upgraded ✓
└── Logged in
December 15, 2024
├── 10:00 AM - Onboarding flow
└── Account created, identified
November 28, 2024 (anonymous)
├── Demo request submitted → Identified
├── /pricing (8 min)
└── /features (5 min)
October 20, 2024 (anonymous)
├── /blog/guide (4 min)
└── First visit via Google search
Cross-Device Tracking
When user logs in on multiple devices:
Devices Used:
Desktop (Chrome/Windows)
├── 18 sessions
└── Last: Today
Mobile (Safari/iOS)
├── 4 sessions
└── Last: Jan 10
Tablet (Chrome/iPad)
├── 2 sessions
└── Last: Dec 20
All sessions linked to john@acme.com
CRM Integration
Supported CRMs
Enterprise Plan| CRM | Sync Type |
|---|---|
| Salesforce | Bi-directional |
| HubSpot | Bi-directional |
| Pipedrive | One-way |
| Zoho | One-way |
Setup CRM Sync
- Go to your domain settings → Integrations tab
- Click on your CRM
- Authorize connection
- Configure field mapping
- Enable sync
Field Mapping
Map Zenovay fields to CRM:
| Zenovay Field | CRM Field |
|---|---|
| name | Name |
| company | Account |
| visits | Custom: Total Visits |
| last_seen | Custom: Last Website Visit |
| score | Custom: Engagement Score |
Data Flow
From Zenovay to CRM:
- User properties
- Visit activity
- Page views
- Goals completed
- Engagement score
From CRM to Zenovay:
- Contact owner
- Deal stage
- Account info
- Custom fields
Sync Triggers
Choose when to sync:
| Trigger | Description |
|---|---|
| Real-time | Sync immediately |
| Hourly | Batch every hour |
| Daily | Batch daily |
| On event | Specific actions |
User Segments
Create Segments
Group users by behavior:
Segment: Power Users
Conditions:
• Sessions > 10
• Goals completed > 3
• Last seen within 7 days
Results: 156 users
Segment Examples
| Segment | Criteria | Count |
|---|---|---|
| Trial Users | plan = "trial" | 245 |
| Active Enterprise | plan = "enterprise" AND last_seen < 7 days | 89 |
| At Risk | sessions > 5 AND last_seen > 30 days | 34 |
| High Value | revenue > $1000 | 156 |
Use Segments For
- Targeted analysis
- Export lists
- CRM sync rules
- Alert triggers
User Alerts
Set Up Alerts
Get notified for user activity:
Alert: Key User Active
Trigger: User in segment "Enterprise" visits
Delivery: Slack #customer-success
Alert Types
| Alert | Trigger |
|---|---|
| User identified | New identification |
| Segment entry | User matches segment |
| Goal completed | Specific goal |
| Inactivity | No visit in X days |
Privacy Considerations
User Consent
Before identifying:
- Ensure proper consent
- Follow privacy policy
- Respect opt-outs
Data Handling
User data is:
- Encrypted at rest
- Encrypted in transit
- Access controlled
- Retained per plan
User Deletion
To delete user data:
- Go to your domain settings → Security tab
- Enter user ID/email
- Confirm deletion
- Data removed within 30 days
Opt-Out Respect
// Check for opt-out before identifying
if (!userHasOptedOut()) {
zenovay('identify', userId, userData);
}
API Access
Get User Data
GET /api/v1/users/{user_id}
Response:
{
"id": "user_12345",
"email": "john@acme.com",
"name": "John Smith",
"company": "Acme Corporation",
"properties": {
"plan": "enterprise",
"role": "admin"
},
"stats": {
"sessions": 24,
"pages_viewed": 89,
"goals_completed": 5,
"revenue": 4999
},
"first_seen": "2024-10-20T15:30:00Z",
"identified_at": "2024-11-15T10:00:00Z",
"last_seen": "2025-01-15T14:30:00Z"
}
List Users
GET /api/v1/users?limit=50&segment=enterprise
Response:
{
"users": [...],
"total": 89,
"page": 1
}
Best Practices
Identify Early
Identify as soon as possible:
- On signup/login
- On form submission
- When email known
Use Consistent IDs
Pick one ID strategy:
- Email (if unique)
- User ID from database
- UUID
Update Properties
Keep properties current:
// When user upgrades plan
zenovay('identify', userId, {
plan: 'enterprise',
upgraded_at: new Date()
});
Don't Over-Identify
Avoid calling identify:
- On every page load
- For anonymous visitors
- Without user consent
Troubleshooting
User Not Identified
If identification fails:
- Check console for errors
- Verify tracking script loaded
- Confirm identify called after script
History Not Linked
If past visits don't appear:
- Cookies may have been cleared
- Different browser/device
- Incognito mode used
CRM Not Syncing
If data doesn't sync:
- Check CRM connection
- Verify field mapping
- Review sync logs