# Identify Users

Use `identify` when you know who a user is. Identification connects anonymous or device-level activity to a stable user ID and stores traits such as plan, role, or account tier.

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

## When to call it

Call `identify()` as soon as your application establishes or restores authenticated user state:

- after sign-up
- after login
- on application load when the user is already authenticated

Client-side SDKs can link the anonymous activity that happened before login to the stable user ID. Server-side SDKs and direct API clients should pass the `distinct_id` and traits explicitly.

## SDK examples

Update user or account traits when they change. Keep traits focused on fields you expect to analyze, filter, or join against:

### TypeScript

```typescript
altertable.updateTraits({ plan: 'enterprise', onboarding_completed: true });
```

### React

```tsx
function UpgradeButton() {
  const { updateTraits } = useAltertable();

  return (
    <button onClick={() => updateTraits({ plan: 'enterprise' })}>
      Upgrade plan
    </button>
  );
}
```

### Python

```python
# No updateTraits() helper; identify the user again with updated traits.
client.identify(distinct_id="user_123", options={"traits": {"plan": "enterprise"}})
```

### Ruby

```ruby
# No updateTraits helper; identify the user again with updated traits.
Altertable.identify('user_123', traits: { plan: 'enterprise' })
```

### Swift

```swift
client.updateTraits(["plan": "enterprise"])
```

### Kotlin

```kotlin
Altertable.shared?.updateTraits(mapOf("plan" to "enterprise"))
```

On client-side SDKs, call `reset()` on logout so later activity is not attributed to the previous user:

### TypeScript

```typescript
// Reset identity, keep device ID
altertable.reset();

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

### React

```tsx
function LogoutButton() {
  const { reset } = useAltertable();

  return <button onClick={() => reset()}>Log out</button>;
}
```

### Python

```python
# The Python SDK has no reset() method; it does not retain a client-side identity.
# Pass the next user's distinct_id explicitly on subsequent calls.
```

### Ruby

```ruby
# The Ruby SDK has no reset method; it does not retain a client-side identity.
# Pass the next user's ID explicitly on subsequent calls.
```

### Swift

```swift
client.reset()
```

### Kotlin

```kotlin
// Reset identity, keep device ID
Altertable.shared?.reset()

// Reset all IDs including device ID
Altertable.shared?.reset(resetDeviceId = true)
```

## API reference

For HTTP request details, response shape, and error codes, see [`POST /identify`](/docs/api-references/product-analytics.md#post-identify).

## Best practices

- Use stable, immutable IDs from your own user system.
- Avoid mutable identifiers such as email addresses as `distinct_id`.
- Keep traits current as account state changes.
- Avoid secrets and regulated sensitive data in traits.