Skip to content

Identify

tracing.identify() attaches traits to the current visitor. Traits are not events: they describe the person, they are stored once per visitor per key, and a later call overwrites an earlier one.

tracing.identify({
userId: "u_8213",
email: "ada@acme.com",
plan: "pro",
seats: 5,
});

The call sends one hit of type identify. The collector writes the traits and returns immediately: no event row, no pageview, nothing that affects a count. An identify hit will not create a session, will not end a bounce, and will not appear in Journeys.

Traits are upserted on (site, visitor, key), so calling it again with a different value updates that key and leaves the others alone.

Rule Value
Traits per call first 50 are stored
Key length truncated to 200 characters
String value length truncated to 500 characters
Numbers stored in a numeric column as well as a string
Booleans and everything else stringified
Repeat calls overwrite the same key for the same visitor

Call it as soon as you know who the visitor is, on every page load where you know — not once at sign-in.

// after your auth state is ready
if (user) {
tracing.identify({ userId: user.id, email: user.email, plan: user.plan });
}

Retention has two modes. Visitors counts the raw daily hash, which is honest for same-day return and structurally near zero across days. Identified users retains a durable id taken from the traits — and it only looks at four keys, in this order:

userId → user_id → id → email

The first one present, with a non-empty string value, is the visitor’s durable id. A visitor carrying none of them is excluded from identified retention entirely rather than counted as churned, so the grid describes the population you can actually measure.

email is last on purpose: a user id is stable across an address change, an email is not.

Which keys show a person in the Sessions list

Section titled “Which keys show a person in the Sessions list”

The Identified column on Sessions — and the same label in the visit drawer — uses a wider, differently ordered list, best first:

email → user_email → userEmail → userId → user_id → username → name

That list is display-only. It never affects a count. If you want the Sessions list to read as email addresses and identified retention to key on your internal id, send both email and userId.

Two query parameters, available on every filterable screen:

Parameter Meaning
traitKey Keep only visitors who have this trait key
traitValue Narrow to one value of that key
/dashboard/<siteId>?range=30d&traitKey=plan&traitValue=pro

The filter is applied at the visitor level: it keeps events whose visitor has a matching trait row, so a filtered screen reads “everything these people did”, not “the events that happened to carry the trait”.

The Sessions search box also matches trait values, so typing an email address there finds that person’s visits for the day.

Traits are stored exactly as you send them, in your own database row, and anyone with dashboard access can read them.

  • Do not send passwords, tokens, payment details, health data or anything in a special category.
  • Prefer an opaque userId over an email where a join is all you need.
  • Remember that you are the controller of whatever you put here. The product is cookieless by default, but sending a person’s email address through identify() is a decision you made, with the notice and legal-basis obligations that come with it.
  • Resetting a site from Settings → Danger zone deletes every trait for that site along with the events and sessions.

See What is stored and Data processing notes.