identify()
The identify() method links an anonymous visitor to a known user identity. Call it when you know who the user is — after login, registration, or when the user updates their profile.
Syntax
_df.identify(userId, traits?)Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
userId | string | Yes | A unique, stable identifier for the user (e.g., database ID) |
traits | Record<string, unknown> | No | Key-value pairs describing the user (email, name, plan, etc.) |
Returns
void
Basic usage
_df.identify('user-123');With traits
_df.identify('user-123', {
email: 'jane@example.com',
name: 'Jane Doe',
plan: 'professional',
createdAt: '2025-03-15T00:00:00Z',
});When to call identify()
Call identify() whenever the user’s identity becomes known or their traits change:
| Scenario | Example |
|---|---|
| After login | User signs in with email/password or SSO |
| After registration | User completes the sign-up flow |
| After profile update | User changes their name, email, or plan |
| On page load (authenticated) | User returns to a page where they are already logged in |
// After successful login
async function handleLogin(email, password) {
const response = await api.login(email, password);
const user = response.data;
_df.identify(user.id, {
email: user.email,
name: user.name,
plan: user.plan,
});
}// On page load when already authenticated
if (currentUser) {
_df.identify(currentUser.id, {
email: currentUser.email,
name: currentUser.name,
});
}How identity works
When identify() is called:
- The
userIdis stored in memory and included in all subsequent events - The
traitsare merged with any previously set traits (new values overwrite existing keys) - An
identifyevent is sent to the Ingestion Gateway - The server links the
userIdto theanonymousId, creating a unified user profile
Before identify():
anonymousId: "a1b2c3d4-..." (unknown visitor)
After identify('user-123'):
anonymousId: "a1b2c3d4-..." (linked)
userId: "user-123" (known user)All subsequent page() and track() calls will include both anonymousId and userId, allowing the server to attribute pre-login activity to the identified user.
PII handling
Traits containing personally identifiable information (PII) such as email, name, and phone are hashed server-side using SHA-256 before being delivered to vendor APIs. The raw PII is stored only in your own database and is never sent to third-party vendors in plaintext.
This is how Datafly enables features like Meta’s Advanced Matching and Google’s Enhanced Conversions without exposing raw user data:
| Trait | What vendors receive | Used for |
|---|---|---|
email | SHA-256 hash | Meta Advanced Matching, Google Enhanced Conversions |
phone | SHA-256 hash (E.164 format) | Meta Advanced Matching, TikTok matching |
name | SHA-256 hash (first + last) | Meta Advanced Matching |
firstName | SHA-256 hash | Meta Advanced Matching |
lastName | SHA-256 hash | Meta Advanced Matching |
You send the raw values in identify() traits. The Datafly server handles normalisation (lowercasing, trimming, formatting) and hashing before delivery.
Trait merging
Traits are merged across multiple identify() calls. New values overwrite existing keys, but keys not included in a subsequent call are preserved:
// First call
_df.identify('user-123', { email: 'jane@example.com', plan: 'starter' });
// Later call -- plan is updated, email is preserved
_df.identify('user-123', { plan: 'professional' });
// Internal state now: { email: 'jane@example.com', plan: 'professional' }Common traits
| Trait | Type | Description |
|---|---|---|
email | string | Email address |
name | string | Full name |
firstName | string | First name |
lastName | string | Last name |
phone | string | Phone number (preferably E.164 format) |
plan | string | Subscription plan or tier |
createdAt | string | ISO 8601 date when the user account was created |
company | string | Company name (alternative to using group()) |
title | string | Job title |
address | object | Address object ({ city, state, country, postalCode }) |
Event payload
An identify() call produces an event with type: "identify":
{
"type": "identify",
"anonymousId": "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d",
"userId": "user-123",
"traits": {
"email": "jane@example.com",
"name": "Jane Doe",
"plan": "professional"
},
"context": {
"page": {
"url": "https://example.com/dashboard",
"path": "/dashboard",
"referrer": "https://example.com/login",
"title": "Dashboard",
"search": ""
},
"screen": { "width": 1920, "height": 1080 },
"locale": "en-US",
"timezone": "America/New_York",
"userAgent": "Mozilla/5.0 ...",
"library": { "name": "@datafly/collector", "version": "0.1.0" }
},
"timestamp": "2026-02-25T14:22:00.000Z",
"messageId": "df-c3d4e5f6-a7b8-4c9d-0e1f-2a3b4c5d6e7f"
}The userId should be a stable, unique identifier from your system — typically a database primary key or UUID. Do not use email addresses as the userId, because users may change their email. Pass the email as a trait instead.