Documentation
Identifying Users

Identifying Users

Identification connects behavioral events to a stable user identity. This is what lets you answer questions about a person across sessions, devices, and visits instead of treating each session as unrelated activity.

In practice, identify() is the moment when your analytics move from "someone did this" to "this user did this".

When to call identify()

Call identify() as soon as you know who the user is:

  • right after sign-up
  • right after login
  • on application load if the user is already authenticated

On client-side SDKs, this links the anonymous activity that happened before login to the user's stable ID. On server-side SDKs, there is no automatic anonymous session, so calling identify() primarily updates traits for the distinct_id you provide.

Most applications follow this sequence:

  1. Let anonymous visitors generate events before login.
  2. When the user authenticates, call identify() with your stable internal user ID.
  3. Include useful traits such as plan, role, or account tier.
  4. Continue tracking events normally. Future analysis can now connect them to the identified user.
  5. On logout, call reset() in client SDKs so later activity is not attributed to the previous user.

Identity model

All SDKs and API clients use the same core identity fields:

Concept
Description
environment
Environment slug where the identity should be updated.
distinct_id
Your stable user identifier, for example internal user ID.
traits
User attributes such as plan, email, or account tier.
anonymous_id
Pre-login ID used to connect anonymous behavior to a known user.
timestamp
Optional event time. When provided, traits update only if this timestamp is newer than the current identity state.

SDK examples

Use identify() wherever your application establishes or restores authenticated user state:

import { altertable } from '@altertable/altertable-js';
// Initialize with your API key
altertable.init('YOUR_API_KEY', {
environment: 'production',
});
// Track a user event
altertable.track('checkout_completed', {
revenue: 49.99,
plan: 'pro',
currency: 'USD',
});
// Identify a user
altertable.identify('user_abc123', {
plan: 'pro',
});

Anonymous users

You can track events without identifying users. Client-side SDKs automatically assign a device-based distinct_id to anonymous visitors.

When you call identify(), the SDK links the anonymous visitor ID to the authenticated user ID. The previous distinct_id becomes the anonymous_id in the identify payload, connecting pre-login behavior to the known user.

Server-side SDKs require you to pass a distinct_id with each call. Use your own anonymous ID (e.g. a session token) until the user authenticates.

Updating user traits

After identifying a user, update their traits as account state changes. This keeps user profiles, cohort definitions, and event enrichment aligned with the latest account state.

Client-side SDKs provide a dedicated method so you don't need to pass the user ID again:

client.identify(distinct_id="user_123", options={"traits": {"plan": "enterprise"}})

Server-side SDKs update traits by calling identify() again with the new trait values.

Session management

Client-side SDKs track session and device state automatically. Call reset() on logout to clear the current identity context so future events are not associated with the previous user:

// Reset identity, keep device ID
altertable.reset();
// Reset all IDs including device ID
altertable.reset({ resetDeviceId: true });

When to reset:

  • On logout, so events aren't attributed to the previous user.
  • For privacy compliance, when users clear their data or revoke consent.

Common identity decisions

Use a stable ID from your own system for distinct_id, such as an internal user ID. Avoid mutable identifiers such as email addresses whenever possible, because they can change and make longitudinal analysis harder to reason about.

Traits should describe the current state of the user or account, not serve as a place to duplicate every field from your application database.

Direct API usage

Endpoint: POST https://api.altertable.ai/identify

curl -X POST "https://api.altertable.ai/identify?sync=true" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"environment":"production",
"distinct_id":"u_01jza857w4f23s1hf2s61befmw",
"anonymous_id":"anon_123abc",
"traits":{"plan":"premium","email":"[email protected]"}
}'

Set sync=true when you want the API to wait for the identify task to finish before returning.

Batch requests

Like /track, the identify API accepts either one payload or an array:

curl -X POST https://api.altertable.ai/identify \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '[
{
"environment":"production",
"distinct_id":"user_123",
"traits":{"plan":"starter"}
},
{
"environment":"production",
"distinct_id":"user_456",
"traits":{"plan":"enterprise"}
}
]'

Query identity traits

SELECT
distinct_id,
traits->>'email' AS email,
traits->>'plan' AS plan,
updated_at
FROM altertable.analytics.identities
ORDER BY updated_at DESC;

Querying events with identity traits

SELECT
e.event,
e.properties,
e.timestamp,
e.identity_traits->>'email' AS email,
e.identity_traits->>'plan' AS plan
FROM altertable.analytics.events e
WHERE e.distinct_id = 'u_01jza857w4f23s1hf2s61befmw'
ORDER BY e.timestamp DESC;

Best practices

  • Identify immediately after authentication (this includes after a full page load/reload if the user is already authenticated).
  • Use stable IDs from your own user system, preferably immutable internal IDs.
  • Keep traits current as account state changes, and use timestamps if updates may arrive out of order.
  • Always send the target environment so identities are written to the correct workspace.
  • Never send secrets or regulated sensitive data in traits.
  • Reset identity context on logout in client SDKs.
Crafted with <3 by former Algolia × Front × Sorare builders© 2026 AltertableTermsPrivacySecurityCookies