# Identify

Identify links an anonymous visitor to a user of your app. Then the visitor's journey, goals and payments show a real user, and payments can match by email.

## From the browser

Call it after sign-in and after signup, when you know the user:

~~~js
window.twelvebit?.("identify", {
  user_id: "u_8f2a",           // your opaque user id
  email: "ada@example.com",
  name: "Ada Lovelace",
  image: "https://example.com/avatars/ada.png", // or avatar
  plan: "pro",                 // any other key is stored as a trait
});
~~~

- `user_id` or `email` is required. Without both, the script logs a warning and sends nothing.
- `name` replaces the friendly random name (`amber-fox-4821`) in the dashboard.
- `image` (or `avatar`) shows in journeys and on the live view.
- Other keys are stored as traits. Later calls merge into earlier traits.

## From your server

~~~sh
curl -sS -X POST https://twelvebit.app/api/v1/identify -H "Authorization: Bearer $TWELVEBIT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"visitor_id": "VISITOR_ID", "user_id": "u_8f2a", "email": "ada@example.com", "name": "Ada Lovelace", "traits": {"plan": "pro"}}'
~~~

| Field | Type | Notes |
|---|---|---|
| `visitor_id` | string | Required. The value of the `_tb_vid` cookie. |
| `user_id` | string | Your user id. |
| `email` | string | Lets twelvebit match payments by email. |
| `name` | string | Display name. |
| `traits` | object | Flat strings, numbers or booleans. Merged into earlier traits. |

## Privacy

- Identify only where your privacy policy and consent allow it. Some laws need consent before you link analytics to a person.
- Use an opaque `user_id`, not an email, as the id.
- Never put personal data in event props. Identify is the one place for identity.
- In [cookieless mode](/docs/privacy#cookieless-mode) the visitor id changes every day, so an identify call links only that day's visitor.

---

Source: https://twelvebit.app/docs/identify · All docs: https://twelvebit.app/llms.txt
