# Identifying users

Identification links widgets to real users: progress persists across devices, and targeting rules can use user attributes. Without it, visitors are anonymous.

## The call

```js
window.Produktly.identifyUser(userId, metadata, options)
```

Signature facts (positional arguments, NOT an options object):
- `userId` (required): your stable, unique user id (primary key / UUID). String or number; coerced to a string server-side.
- `metadata` (optional object): attributes for targeting and personalization, e.g. `{ plan: "pro", role: "admin", companyId: 42, createdAt: "2026-01-01" }`. Primitive values preferred; nested objects are accepted. Top-level keys automatically become available as targeting attributes in the dashboard.
- `options` (optional): `{ hash }` — HMAC-SHA256 identity-verification hash, only needed if "Require identity verification" is enabled in the company settings.

Call it right after your app knows who the user is (post-login, on session restore). Calling before the Produktly script finishes loading is safe — calls are queued.

IMPORTANT: `identifyUser` REPLACES the stored metadata for that user (it does not merge). Send the full attribute set each time, or use the server-side PATCH endpoint for partial updates.

On logout call `window.Produktly.clearCurrentUser()`.

## Personalization

Widget text supports templates against these attributes: `{{user.plan}}`, `{{user.name | there}}` (with fallback) in tour/checklist content.

## Server-side alternative (REST)

With a private API key (`Authorization: Bearer <key>`, base `https://api.produktly.com/api/v1`):
- `PATCH /users/:userId` — merge attributes (a null value removes a key); creates the user if missing.
- `PUT /users/:userId` — replace (same behavior as identifyUser).
- `GET /users/:userId`, `DELETE /users/:userId`.
Limit: metadata ≤ 32 KB serialized; 300 requests/min per key on /users.

## waitForUser

If the install snippet sets `data-wait-for-user="true"`, no widgets load until `identifyUser` runs — recommended for logged-in products so targeting always sees user attributes.
