> ## Documentation Index
> Fetch the complete documentation index at: https://docs.joinrefine.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Identity Management

> Manage visitor, session, and user identity for personalization and tracking

## Overview

Refine tracks three levels of identity to power personalization and analytics:

| Level       | Persistence            | Identifier     |
| ----------- | ---------------------- | -------------- |
| **Visitor** | Browser (localStorage) | Auto-generated |
| **Session** | Tab lifetime + timeout | Auto-generated |
| **User**    | Cross-device           | Your user ID   |

## Identity Hierarchy

```
                    ┌─────────────┐
                    │   User ID   │  ← Your identifier (login)
                    │ (optional)  │
                    └──────┬──────┘
                           │
                    ┌──────▼──────┐
                    │ Visitor ID  │  ← Auto-generated, persisted
                    │ (required)  │     in localStorage
                    └──────┬──────┘
                           │
                    ┌──────▼──────┐
                    │ Session ID  │  ← Auto-generated per session
                    │ (required)  │     30 min timeout
                    └─────────────┘
```

## Visitor ID

Automatically generated on first SDK use and stored in localStorage.

```typescript theme={null}
// Get current visitor ID
const visitorId = refine.getVisitorId();
console.log(visitorId);  // e.g., "v_a1b2c3d4e5f6"
```

**Characteristics:**

* Generated once per browser/device
* Persists across sessions (survives page refresh, browser close)
* Does not persist across devices or browsers
* Used for visitor-based recommendations

<Note>
  In incognito/private mode, visitor IDs are cleared when the browser closes.
</Note>

## Session ID

Automatically generated for each browsing session.

```typescript theme={null}
// Get current session ID
const sessionId = refine.getSessionId();
console.log(sessionId);  // e.g., "s_x9y8z7w6v5"
```

**Characteristics:**

* Generated when SDK initializes
* Expires after 30 minutes of inactivity (configurable)
* New session created after timeout
* Used to group interactions within a visit

### Configure Session Timeout

```typescript theme={null}
const refine = new Refine({
  apiKey: process.env.REFINE_API_KEY,
  organizationId: 'org_abc123',
  catalogId: 'cat_xyz789',
  events: {
    sessionTimeout: 60 * 60 * 1000  // 1 hour instead of 30 minutes
  }
});
```

## User ID

Your application's identifier for logged-in users. Set via `identify()`.

```typescript theme={null}
// When user logs in
refine.identify('user_12345');

// Get current user ID
const userId = refine.getUserId();
console.log(userId);  // "user_12345"
```

**Characteristics:**

* Set by your application
* Links visitor behavior to a known user
* Enables cross-device personalization
* Required for user-based recommendations

## The identify() Method

Call `identify()` when a user logs in:

```typescript theme={null}
// After successful login
async function handleLogin(credentials: Credentials) {
  const user = await authenticateUser(credentials);
  
  // Link visitor to user
  refine.identify(user.id);
  
  // Now user recommendations are available
  const recs = await refine.recs.forUser({
    configId: 'personalized',
    topK: 12
  });
}
```

### Identity Merging

When you call `identify()`, Refine links the current visitor's browsing history to the user account:

```typescript theme={null}
// Anonymous visitor browses products
await refine.search.text({ query: 'running shoes', topK: 20 });
// Interactions tracked under visitor_abc123

// User logs in
refine.identify('user_789');
// Previous visitor_abc123 interactions now linked to user_789

// Future interactions tracked under user_789
await refine.search.text({ query: 'trail shoes', topK: 20 });
```

## The reset() Method

Call `reset()` when a user logs out:

```typescript theme={null}
function handleLogout() {
  // Clear user identity
  refine.reset();
  
  // User is now back to anonymous visitor
  // A new visitor ID will be generated
}
```

**What reset() does:**

* Clears the user ID
* Generates a new visitor ID
* Generates a new session ID
* Clears any cached personalization

<Warning>
  After `reset()`, previous browsing behavior is no longer linked to subsequent sessions. Call this on logout to preserve user privacy.
</Warning>

## Identity in Events

All events automatically include identity information:

```typescript theme={null}
// Event payload (internal)
{
  visitorId: "v_abc123",
  sessionId: "s_xyz789",
  userId: "user_12345",  // null if not identified
  event: "click",
  ...
}
```

## Complete Authentication Flow

```typescript theme={null}
import { Refine } from '@refine-ai/sdk';

const refine = new Refine({
  apiKey: process.env.REFINE_API_KEY,
  organizationId: 'org_abc123',
  catalogId: 'cat_xyz789'
});

class AuthManager {
  async init() {
    // Check for existing auth
    const user = await this.getStoredUser();
    if (user) {
      refine.identify(user.id);
    }
  }

  async login(email: string, password: string) {
    const user = await api.login(email, password);
    
    // Link visitor to user
    refine.identify(user.id);
    
    // Store auth
    this.storeUser(user);
    
    return user;
  }

  async logout() {
    await api.logout();
    
    // Clear Refine identity
    refine.reset();
    
    // Clear stored auth
    this.clearStoredUser();
  }

  private async getStoredUser() {
    // Your auth storage logic
  }

  private storeUser(user: User) {
    // Your auth storage logic
  }

  private clearStoredUser() {
    // Your auth storage logic
  }
}

// Usage
const auth = new AuthManager();
await auth.init();

// Get appropriate recommendations
async function getRecommendations() {
  if (refine.getUserId()) {
    // Logged in - use user recommendations
    return refine.recs.forUser({ configId: 'user_picks', topK: 12 });
  } else {
    // Anonymous - use visitor recommendations
    return refine.recs.forVisitor({ configId: 'visitor_picks', topK: 12 });
  }
}
```

## Server-Side Identity

For server-side rendering or API routes, pass identity explicitly:

```typescript theme={null}
// Server-side (e.g., Next.js API route)
import { Refine } from '@refine-ai/sdk';

const refine = new Refine({
  apiKey: process.env.REFINE_API_KEY,
  organizationId: 'org_abc123',
  catalogId: 'cat_xyz789',
  applicationType: 'server'
});

export async function getServerSideProps(context) {
  const userId = context.req.session?.userId;
  
  if (userId) {
    refine.identify(userId);
    const recs = await refine.recs.forUser({
      configId: 'personalized',
      topK: 12
    });
    return { props: { recommendations: recs.results } };
  }
  
  // For anonymous users, use visitor recommendations on client
  return { props: { recommendations: [] } };
}
```

## Privacy Considerations

### GDPR Compliance

```typescript theme={null}
const refine = new Refine({
  apiKey: process.env.REFINE_API_KEY,
  organizationId: 'org_abc123',
  catalogId: 'cat_xyz789',
  privacy: {
    respectDoNotTrack: true,  // Honor browser DNT setting
    anonymizeIp: true,        // Anonymize IP addresses
    requireConsent: true      // Wait for consent before tracking
  }
});
```

### Data Deletion

When a user requests data deletion:

1. Call `refine.reset()` on their device
2. Contact Refine support for server-side deletion

## Debugging Identity

```typescript theme={null}
const refine = new Refine({
  apiKey: process.env.REFINE_API_KEY,
  organizationId: 'org_abc123',
  catalogId: 'cat_xyz789',
  debug: true
});

// Check current identity
console.log('Visitor:', refine.getVisitorId());
console.log('Session:', refine.getSessionId());
console.log('User:', refine.getUserId());

// After identify
refine.identify('user_123');
console.log('User after identify:', refine.getUserId()); // 'user_123'

// After reset
refine.reset();
console.log('User after reset:', refine.getUserId()); // null
console.log('Visitor after reset:', refine.getVisitorId()); // New ID
```

## Next Steps

<CardGroup cols={2}>
  <Card title="User Recommendations" icon="user-check" href="/sdk/recommendations/user-recommendations">
    Personalization for logged-in users
  </Card>

  <Card title="Consent Plugin" icon="shield-check" href="/sdk/plugins/consent-plugin">
    GDPR-compliant consent management
  </Card>
</CardGroup>
